C语言程序设计教案-第十章指针_第1页
C语言程序设计教案-第十章指针_第2页
C语言程序设计教案-第十章指针_第3页
C语言程序设计教案-第十章指针_第4页
C语言程序设计教案-第十章指针_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第十章 指 针课题:第十章 指针 1-2教学目的:1、了解指针与地址的概念2、掌握指针变量的定义、初始化及指针的运算教学重点:教学难点:指针变量的定义、初始化及指针的运算指针的运算步骤一 复习引导 指针是C语言的一个重要概念,也是C语言的一个重要特色。正确而灵活地运用它,可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而方便地使用数组;在调用函数时能得到多于1个的值;能直接处理内存地址等,这对设计系统软件是很必要的。 指针的概念比较复杂,使用也比较灵活,因此初学者时常会出错,务请在学习本章内容时十分小心。步骤二 讲授新课10.1 地址和指针的概念计算机的主存储器被分成一个

2、个存储单元,为了区分各存储单元,要为每个存储单元编号,这个编号即地址。 例:i =3; 或 scanf(“%d”, &i); 是将3送给 i所在的空间。 例:将3送到变量I_pointer所“指向”的单元(即I所标志的单元)。 所谓“指向”,是通过地址来体现的,I_pointer中的值为2000,它是变量I 的地址,这样就在I_pointer和变量之间建立起一种联系,即通过I_pointer能知道I的地址,从而找到变量I的内存单元。因而在C语言中,将地址形象化地称为“指针”。 意思是通过它能找到以它为地址的内存单元。一个变量的地址称为该变量的“指针”。 内存单元的地址和内存单元的内容是两个不同

3、的概念。 指针:就是地址,即内存单元的编号。 指针变量:用来存放另一变量的地址(即指针)的变量。 如:地址2000是变量 i的指针;i_pointer是指针变量,其值就是指针2000。10.2变量的指针和指向变量的指针变量 变量的指针就是变量的地址。 存放变量地址的变量是指针变量,用来指向另一个变量。 *i_pointer 表示 i_pointer 所指向的变量。一、定义一个指针变量指针变量的定义包含三个方面的内容: 指针类型说明,即定义变量为一个指针变量 指针变量名 变量值(指针)所指向的变量的数据类型。格式: 存储类型 基类型 *指针变量名;例:int *pointer_1, *point

4、er_2; float *pointer_3; char *pointer_4;二、指针的引用指针变量有两个运算符:& :取地址运算符 功能:取变量地址;单目,右结合。 * :取内容运算符(“间接访问”运算符) 功能:只能跟地址,取变量所指向单元的内容;单目,右结合。 例:&a为变量a的地址, *p 为指针变量p所指向的存储单元。 例:int a=5, *p=&a; printf ( “%d”, *p );main() int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=&a; /*把变量a的地址赋给pointer_1*/ poi

5、nter_2=&b; /*把变量b的地址赋给pointer_2*/ printf(“%d,%dn”,a,b); printf(“%d,%dn”,*pointer_1, *pointer_2);输出结果:100, 10 100, 10评注: 1、在第3行虽然定义了两个指针变量,只是提供了两个指针变量,但并未指向任何一个整型变量。称为指针“悬空”。 2、最后一行的*pointer_1和pointer_2就是变量a和b。 3、程序中两处出现*pointer_1等,含义不同。程序第3行中的*pointer_1表示定义指针变量pointer_1。它前面的*只是表示该变量是指针变量。程序最后一行中的*po

6、inter_1则代表变量,即pointer_1所指向的变量。 4、第5行中的pointer_1=&a 是将a的地址赋给指针变量pointer_1,而不是*pointer_1。 注意:不应写成:*pointer_1=&a; 5、从上例中可看出,*pointer_1等价于a,*pointer_2等价于b,故凡在程序中出现a的地方均可用 *pointer_1 代替。所以,若有: int x, y, *px=&x ;则下面的运算均是正确的: y=*px+1; /*把 x 的内容加1 送变量y*/printf(“%dn”, px ); /*打印当前x 的内容*/d=sqrt(double) px); /

7、*把x的平方根送变量d*/px=0; /*把 x 置为0*/*px+=1; /*把 x 的值加 1*/(*px)+; /*使 x 的值加 1*/y=(*px)+; /*即y=x, x+*/6、假设px和py都被定义为指向int 对象的指针,而且px当前已指向了int 型变量x,则执行: py=px; /*把指针px的内容拷贝到指针py中去*/即 py和px 这两个不同的指针指向了同一对象x7、指针不是整数,不能将它与整数混为一谈。例:# include main() int x=100,*p;p=x;printf(“%d”, p ); 例如:# include main() int a, b,

8、 *d=&a; b = d; printf( “%d n”, b ); 编译不出错,但得不到希望的值关于&和*运算符的说明: 假设已执行 pointer_1=&a; 1、&*pointer_1含义是什么? &*pointer_1与&a相同,即变量a的地址。 2、*&a的含义是什么? 先进行&a运算,得a的地址,再进行*运算。 *&a、*pointer_1及变量a等价。 3、(*pointer_1) + + 相当于a + +。 它与*pointer_1 + + 不同。 4、*pointer_1 + + 等价于*(pointer_1 + +),即先进行*运算,得到a的值,然后使pointer_1的

9、值改变,这样pointer_1不再指向a了。例10.2:输入a和b两个整数,按先大后小的顺序输出a和b。main() int *p1,*p2,*p, a, b; scanf(“%d,%d”,&a,&b); p1=&a; p2=&b; if (ab) p=p1; p1=p2; p2=p; printf(“n a=%d,b=%dn”,a,b); printf(“max=%d,min=%dn”,*p1,*p2);运行情况:5,9a=5,b=9max=9,min=5三、指针变量作为函数参数例10.3对输入的两个整数按大小顺序输出。先考察如下程序,看是否能得到预期的结果 swap(int p1, int

10、 p2) int temp; temp = p1; p1 = p2; p2 =temp;main() int a, b; scanf(“%d, %d”, &a, &b); if(ab) swap(a, b); printf(“n%d,%dn”,a,b);不能得到预期的结果。改为:swap(int *p1,int *p2) int temp; temp = *p1; *p1 = *p2; *p2 =temp;main() int a,b; int *pointer_1,*pointer_2; scanf(“%d,%d”,&a,&b); pointer_1=&a; pointer_2=&b; if

11、(ab) swap(pointer_1,pointer_2); printf(“n%d,%dn”,a,b);注:如果想通过函数调用得到n个改变的值,可以:1、在主调函数中设n 个变量,用n个指针变量指向它们;2、然后将指针变量作实参,将这n 个变量的地址传给所调用的函数的形参;3、通过形参指针变量,改变该n个变量的值;4、主调函数中就可以使用这些改变了值的变量。四、指针(变量)的初始化指针置初始化值的格式:存储类型 基类型 *指针名=初始化值;如:main() static int a; int *p=&a, *p1=p; 再如: int *p = 0; 或 int *p = NULL;五、指

12、针的运算1、指针的算术运算指针仅能进行加、减算术运算如:p+n , p-n , p+ , p- , +p , -p p-= n , p+= n , p1-p2 等 其中n是整数,p、p1、p2均为指针;施行加法运算时,指针向地址增大的方向移动;施行减法运算时,指针向地址减小的方向移动;移动长度取决于指针的基类型,由计算机决定;如有:int a,b,c, *pt =&a; 则 pt+ 则指针向后移动两个字节;再如:main() int *p1,a=8,b=3; p1=&a; printf(“%d,%dn”, (*p1)+, *p1+); printf(“%d,%dn”,a, *p1); 运行结果

13、:3 , 8 8 , 4注:p1+k = p1+k*sizeof(p1的基类型); p1- k = p1- k*sizeof(p1的基类型);如: strlen(char *s) char *p=s; while(*p!=0)p+; return(p-s); 2、指针的关系运算设指针p1,p2指向同一数组中的元素,则 p1p2为真:表示p1在p2的前面; p1、=、=、!=比较的意义;不可将指针与其他类型的对象作比较;若两指针指向不同数组中的元素,也不可比较;允许将指针与NULL或数值0进行= =或!=的比较,以便判定一个指针是否为空指针。步骤三 课堂小结本课介绍了指针与地址的概念,指针变量的

14、定义、初始化及指针的运算。 指针:就是地址,即内存单元的编号。 指针变量:用来存放另一变量的地址(即指针)的变量。 例如:int a=5, *p=&a; printf ( “%d”, *p );注意:运算符*和&的用法,指针变量的自加自减运算。步骤四 布置作业 课后作业:第十章课后练习.课题:第十章 指针 3教学目的:掌握指针与数组的知识教学重点:教学难点:指向数组的指针变量指向二维数组的指针步骤一 复习引导上节课介绍了指针变量的定义及其赋值。一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组和数组元素(把

15、数组起始地址或某一元素的地址放到一个指针变量中)。步骤二 讲授新课所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。 引用数组元素可以用下标法(如a3),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占内存少,运行速度快)。一、指向一维数组的指针 定义形式: int a10; int *p; p=&a0; 或 p=a; 含义:把数组的首地址赋给指针变量p。 也即: int *p=&a0; 或 int *p=a;二、通过指针引用数组元素 按C的规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一个数组中的下一个元素(而不是简单地加1

16、)。 如果p的初值为&a0,则: p+i a+i &ai,即指向a数组的第i个元素。 *(p+i) *(a+i) ai。 指向数组的指针变量也可以带下标,如pi与*(p+i)等价引用数组元素时,可以用: 1、下标法,如:ai 2、指针法,如:*( a+i ) 或 *( p+i ) 其中,a是数组名,p是指向数组的指针例105:输出数组中的全部元素 假设有一个a数组,整型,有10个元素。用三种方法输出各元素的值:1、下标法:main() int a10, i ; for( i=0; i10 ; i+) scanf(“%d”,&ai); printf(“n”); for( i=0 ; i10; i

17、+) printf(“%d”,ai);2、利用数组名计算数组元素地址,找出元素的值。main() int a10, i ; for( i=0; i10 ; i+) scanf(“%d”,&ai); printf(“n”); for( i=0 ; i10; i+) printf(“%d”,*(a+i);3、用指针变量指向数组元素。main() int a10, *p, i ; for( i=0; i10 ; i+) scanf(“%d”,&ai); printf(“n”); for( p=a; p(a+10); p+) printf(“%d”,*p );评注:1、第1和2种方法执行效率是相同的。

18、2、第3种方法效率高。3、用下标法比较直观。在使用指针变量时,有几个问题要注意:1、 指针变量可以实现使本身的值改变。 如:for(p=a; p(a+10); p+)2、要注意指针变量的当前值。如:要通过指针变量输出a数组的10个元素。main() int a10, i , *p=a; for( i=0; i10 ; i+) scanf(“%d”, p+); printf(“n”); for( i=0 ; i10; i+,p+) printf(“%d”, *p);这个程序输出的并不是a数组中各元素的值。因为第一个 for 循环结束时,p已经指向数组的末尾。再继续下去,p指向的是a数组下面的10

19、个元素,是不可预料的。可加一句为:p=a;3、用指针变量p指向数组元素,可以指到数组以后的内存单元。C编译程序不作下标越界检查。4、注意指针变量的运算。如果p指向数组a, p+ (或 p+=1 ),使p指向下一元素a1。 *p+ 等价 *(p+)。作用是先得到p指向的变量的值(即*p),然后再使p+1p。 *(p+)与*(+p) 不同。前者为a0,后者为a1 (*p)+表示p指向的元素值加1,即(a0)+ 如果p当前指向a数组中第i个元素,则: *(p- -)相当于ai- -,先对p进行*运算,再使p自减; *(+ + p)相当于a+ +i,先使p自加,再作*运算。 *(- - p)相当于a-

20、 -i,先使p自减,再作*运算。三、数组名作函数参数 用数组名作实参,在调用函数时是把数组的首地址传送给形参。即实参数组与形参数组共占同一段内存。 例10.7 将数组a中的n个整数按相反顺序存放。分析:将a0与an-1对换,再将a1和an-2对换,直到将a(n-1)/2与an-int(n-1)/2对换。设i和j,i的初值为0,j的初值为n-1。将ai和aj交换,然后使i的值加1,j的值减1,再将ai和aj交换,直到 i=(n-1)/2为止。void inv(int x, int n) int temp, i, j,m=(n-1)/2; for( i=0; i=m; i+) j=n-1-i ;

21、temp=xi; xi=xj; xj=temp; return;main() int i, a10=3,7,9,11, 0,6,7,5,4,2; printf(“The array: n ”); for( i=0; i10; i+) printf(“%d”,ai); printf(“n”); inv(a,10); printf(“The array : n”); for( i=0; i10; i+) printf(“%d”,ai); printf(“n”); 例10.8 从10个数中找出其中最大值和最小值。int max,min;void max_min_vlue(int array, int

22、 n) int *p,*array_end; array_end=array+n; max=min=*array; /*等价max=min=array0*/ for(p=array+1;pmax) max=*p; else if (*pmin) min=*p; return;main() int i, number10; printf(“enter 10 integer number:n”); for( i=0; i10; i+) scanf(“%d”,&numberi); max_min_value(number,10); printf(“n max=%d,min=%dn”,max.min)

23、;如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况:1、形参和实参都用数组名; main() int a10; f (a,10); f ( int x,int n ) a和x指的是同一个数组2、实参用数组名,形参用指针变量; main() int a10; f( a, 10 ); f( int *x, int n ) 开始时,x指向a03、实参形参都用指针变量;main() int a10, *p; p = a; f ( p, 10 ); f ( int *x, int n ) 实参p和形参x都指向数组a4、实参为指针变量,形参为数组名。main() in

24、t a10, *p; p = a; f( p, 10 ); f ( int x, int n ) p指向数组a,x和a共用同一段内存单元例10.9 用实参指针变量将a数组中n 个整数按相反顺序存放.void inv(int *x, int n) int *p, m, temp, *i, *j; m=(n-1)/2; i=x; j=x+n-1; p=x+m; for( ; i=p; i+, j- - ) temp=*i; *i = *j; *j =temp; return;main() int i, a10,*p=a; printf(“The original array: n ”); for(

25、 i=0; i10; i+,p+) scanf(“%d”, p); printf(“n”); p=a; inv(p,10); printf(“The array is : n”); for( p=a; pa+10; p+) printf(“%d”, *p); printf(“n”);例10.10:用选择法对10个整数排序。main()int *p, i, a10; p=a; for( i=0; i10; i+) scanf(“%d”,p+); p=a; sort(p,10); for( p=a, i=0; i10; i+) printf(“%d”,*p);p+; sort(int x,int

26、n) int i, j, k, t; for( i=0; in-1; i+) k=i; for(j=i+1; jxk) k=j; if( k !=i) t = xi; xi = xk; xk = t; 四、指向二维数组的指针和指针变量1、 二维数组的地址如: int a34A a0 a0 0 a0 1 a0 2 a0 3 A+1 a1 a1 0 a1 1 a1 2 a1 3 A+2 a2 a2 0 a2 1 a2 2 a2 3例:int a34=1,3,5,7,9,11,13,15,17,19,21,23; 设首地址为2000。l ak+p ( 0=k i , 0=pj )等价于&akp, 由

27、此得到: *(ak+p) 等价于akp;l a0与&a00等价;l a+k与&ak0等价,而a0+k与&a0k等价;l *(a+i)可理解为ai,故有如下等价关系: a+0 等价于 a0、 a0+0、 &a00、 *(a+0) a+1 等价于 a1、 a1+0、 &a10、 *(a+1) a+(i-1) 等价于 ai-1、ai-1+0、 &ai-10、 *(a+i-1)l *(a+k)与*ak是不同的,前者相当于ak,是一个地址值;后者相当于*(ak+0)或*&ak0,是数组元素ak0中存储的值。l 数组元素akp就是*(ak+p),即*(*(a+k)+p)步骤三 课堂小结 本课介绍了指向数组

28、的指针,主要是指向一维数组的指针。用指针变量p指向数组a,指针变量p可以+、-,表示指向数组的上一元素或下一元素。但C编译程序不作下标越界检查。使用指针既方便有灵活,但初学者容易搞错。 步骤四 布置作业课后作业:第十章课后练习.课题:第十章 指针 3-4教学目的:在掌握指针与数组的基础上,掌握字符串的指针与指向字符串的指针变量教学重点:教学难点:指向字符串的指针变量用指针处理字符串步骤一 复习引导上节课介绍了指向一维数组的指针及二维数组的地址,指向一维数组的指针也即指向元素的指针,那么指向二维数组的指针是怎样的呢?它有两种类型。步骤二 讲授新课 2、指向二维数组的指针变量(1)指向数组元素的指

29、针变量设指针变量p=a0 (&a00、a、a+0、*(a+0) )计算aij在n*m数组中的位置: 例: for( i=0; i3; i+) for( j=0; j4; j+ ) printf (“%4d”, *(p+i*m+j); printf(“n”); 例:用指针变量输出数组元素的值。main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for( p=a0; pa0+12; p+) if(p-a0)%4 = 0) printf(“n”); printf(“%4d”, *p); 计算aij在n*m数组中的位置:a0+i*m+j(2)行

30、指针(指向由m个元素组成的一维数组的指针变量) 定义:指针基类型 (*指针名)m 其中,m表示二维数组每行有m列; 如: int (*p)3; 于是,p 指向第0行元素的起始存储地址; p+1 指向第1行元素的起始存储地址; p+I 指向第i 行元素的起始存储地址; 而每一行的元素的表示形式为: 第0行元素的表示为 (*p)j; 第1行元素的表示为 (*(p+1)j; 第i 行元素的表示为 (*(p+ I)j;例 : #include main() int (*p)4, j; int a44=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16; for(p=a; pa

31、+4; p+) for(j=0;j4; j+) if( j=3 ) printf(“%4dn”, (*p)j ); else printf(“%4d” , (*p)j ); 改写为:#include main() int (*p)4, i, j; int a44=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16; p=a; for( i=0; i4; i+) for(j=0;j4; j+) printf(j=3?“%4dn”: “%4d” , *(*(p+i )+j) ); 3、多维数组的指针作函数参数 一维数组的地址可以作为函数参数传递,多维数组的地址也可作函数参

32、数传递。在用指针变量作形参以接受实参数组名传递来的地址时,有两种方法: 1、用指向变量的指针变量; 2、用指向一维数组的指针变量。例;有一个班,3个学生,各学4门课,计算总平均分数,以及第n个学生的成绩。main() void average(float *p ,int n); void search(float (*p)4, int n); float score34=65,67,70,60,80,87,90,81, 90,99,100,98; average( *score, 12); /*求12个分数的平均分*/ search(score , 2); /*求第2个学生成绩*/void a

33、verage(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.2fn”,aver);void search(float (*p)4, int n) int i; printf(“the score of No %d are:n”,n); for( i=0; i4; i+) printf(“%5.2f”, *(*(p+n)+i);例10.15 在上题基础上,查找一门以上课程不及格的学

34、生,打印出他们的全部课程的成绩。main() void search(float (*p)4, int n); float score34=65,57,70,60,58,87,90,81),90,99,100,98; search(score, 3);void search(float (*p)4, int n)int i, j, flag; for( j=0; jn; j+) flag = 0; for( i=0; i4; i+) if(*(*(p+j)+i)60) flag =1; if(flag=1) printf(“No %d fails,his scores are:n”,j+1);

35、 for( i=0; iy) z=x; else z=y; return(z);法2:main() int max(int, int); int (*p)( ); int a,b,c; p=max; /*将地址送入p */ scanf(“%d,%d”,&a,&b); c=(*p)(a,b); /*与max(a,b)等价*/ printf(“a=%d,b=%d,max=%d”,a,b,c); 注:int (*p)()定义p是一个指向函数的指针变量,此函数带回整型的返回值。说明:1、 函数的调用可以通过函数名调用,也可以通过函数指针调用。2、(*p)() 表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。3、在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:p=max; 。4、用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名),在(*p)之后的括号中根据需要写上实参。如:c=(*p)(a,b);5、对指向函数的指针变量,像p+n、p+、p-等运算是无意义的。二、用指向函数的指针作函数参数 函数的参数可

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论