Lesson-9(c语言指针)教学课件_第1页
Lesson-9(c语言指针)教学课件_第2页
Lesson-9(c语言指针)教学课件_第3页
Lesson-9(c语言指针)教学课件_第4页
Lesson-9(c语言指针)教学课件_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

6、纪律是自由的第一条件。——黑格尔7、纪律是集体的面貌,集体的声音,集体的动作,集体的表情,集体的信念。——马卡连柯8、我们现在必须完全保持党的纪律,否则一切都会陷入污泥中。——马克思9、学校没有纪律便如磨坊没有水。——夸美纽斯10、一个人应该:活泼而守纪律,天真而不幼稚,勇敢而鲁莽,倔强而有原则,热情而不冲动,乐观而不盲目。——马克思Lesson9(c语言指针)Lesson9(c语言指针)6、纪律是自由的第一条件。——黑格尔7、纪律是集体的面貌,集体的声音,集体的动作,集体的表情,集体的信念。——马卡连柯8、我们现在必须完全保持党的纪律,否则一切都会陷入污泥中。——马克思9、学校没有纪律便如磨坊没有水。——夸美纽斯10、一个人应该:活泼而守纪律,天真而不幼稚,勇敢而鲁莽,倔强而有原则,热情而不冲动,乐观而不盲目。——马克思Lesson9(c语言指针)第九讲善于使用指针2一、地址和指针的概念二、变量的指针(地址)和指针变量三、数组与指针四、字符串与指针五、多维数组的指针六、指向函数的指针七、指针数组八、指向指针的指针主要内容:3直接访问示意图间接访问示意图表示将数值3送到变量i中,可有两种表达方法:(1)将3送到变量i所标志的单元中,即直接访问方式(2)将3送到变量p所指向的单元(变量i)中。即间接访问方式i32000i320002000p注意:我们并不关心变量p的存储地址,对变量p的访问属于直接访问。6二、指针变量1.变量的指针

变量的地址称为变量的指针(变量i的指针为2000)。2.指针变量存储变量地址的变量称为指针变量,用来指向另一个变量(P=&i)

P是指针变量,指针变量的值即指针变量中存放的地址值3.

*操作符

为了表示指针变量与它所指向的变量之间的关系,在程序中用*符号表示“指向”。例如,P代表指针变量,*P则表示P所指向的变量的值。3i20002000P*P以下两个语句作用相同:

i=3;*P=3;

7二、指针变量(续)4.指针变量的定义

inti,j;

int*pointer1,*pointer2;定义形式:基类型*指针变量名;

举例

说明p213:

(1)指针变量名前的*,表示该变量是指针型的变量。指针变量名为pointer1,而非*pointer1。(2)定义指针变量时必须指明基类型,用来指定该指针变量指向变量的类型。(3)赋给指针变量的是变量地址而不能是任意类型的数据(4)指针变量只能存放地址(指针),不要将一整数赋给一指针变量int*pointer_1=100;(wrong)8如何使一个指针变量指向一个变量呢?

使用取地址运算符&

,即:pointer1=&i;pointer2=&j;赋值语句pointer1=&i;实现将变量i的地址保存入指针变量pointer1中。如右图所示。3ipointer1*pointer1你能画出第二个赋值语句的示意图吗?

二、指针变量(续)5.指针运算符&

9二、指针变量(续)6.指针变量的引用

与指针变量有关的两个运算符:

&:取地址运算符

*:间接访问运算符

(1)上例将打印出i的值。(2)*pointer1与普通的整型变量一样使用,但前提是pointer1必须已经明确地指向了某整型变量,或者说指针变量中必须已经存有了某整型变量的起始地址。

例如

i=3;

pointer1=&i;

printf("%d",*pointer1);说明

3ipointer1*pointer110二、指针变量(续)例8-2:输入两个整数,按先大后小输出这两个整数

#include<stdio.h>voidmain(){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("%d%d",a,b);printf("max=%d,min=%d",*p1,*p2);}你能画出程序中指针处理过程的示意图吗?

11二、指针变量(续)7.指针变量作为函数参数函数的实参值是地址,函数的形参应定义为指针类型,此时,实参和形参之间仍然是单向值传递方式。

#include<stdio.h>(例8-3)

voidswap(int*p1,int*p2)

{inttemp;temp=*p1;

*p1=*p2;

*p2=temp;}

voidmain()

{inta,b,*pointer1,*pointer2;

scanf(“%d%d”,&a,&b);

pointer1=&a;pointer2=&b;/*取变量的地址*/

if(a<b)swap(pointer1,pointer2);/*函数调用,实参为指针变量*/

printf(“%d%d”,a,b);/*打印函数调用后,变量a,b的值,观察其变化*/

printf(“%d,%d”,*pointer1,*pointer2);}在被调函数中,通过间接访问,改变了主调函数中实参指针变量所指变量的值。变量a,b的地址被传递到函数的形参变量p1,p2中127.指针变量作为函数参数(例8-5)main()例8-4{inta=3,b=5,*pointer1,*pointer2;pointer1=&a,pointer2=&b;swap3(pointer1,pointer2);printf(“%d,%d\n”,*pointer1,*pointer2);}swap3(int*p1,int*p2){int*temp;temp=p1;p1=p2;p2=temp;}输出:3,5不能企图通过改变指针形参的值而使指针实参的值改变,即形参的值如果发生改变,并不会改变主调函数的实参的值b5&ap2a3&bp1b5&ba3&apointer1pointer2调用前调用后//*temp??13三、数组与指针

数组在内存中占一片连续的存储区,该存储区的大小与数组的元素类型和数组长度有关。每个数组元素占用相同大小的存储空间。利用数组存储区的起始地址,可以逐个获得每个数组元素的存储地址。例如,定义数组inta[10];

1.数组的存储

a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]注:假设数组a的存储区起始地址为2000。20002002200420062000+4*22000+9*2由上图可知,数组元素a[i]的存储地址的计算公式为:数组a的起始地址+i×元素类型占内存的字节数图214C语言规定:

数组名代表数组的起始地址,该地址在程序运行过程中不能修改。即数组名a是个常量。2.指向数组元素的指针

三、数组与指针例如,

inta[10];

int

*p;对指针变量p赋值:p=&a[0];则使p指向了数组的第一个元素。因此,下面对指针变量p赋值的两个语句等价:p=&a[0];p=a;//不是把数组a各元素的值赋给指针变量p因此定义指向数组的指针变量时,可以对其初始化:inta[10];int

*p=a;(或int

*p=&a[0];)15三、数组与指针例如,定义:inta[10],*p=a;

可有如下操作:p=a;

p=&a[1];

*p=10;

3.通过指针变量引用数组元素

4.指针变量表达式和指针的算术运算符

(1)可以对指针进行有限的算术运算,包括自增运算(++)、自减运算(--)、加上一个整数、减去一个整数,以及减去一个指针变量。(2)指针运算的结果依赖于指针所指向的对象的大小。指针的算术运算的规则是:当一个指针加上或减去一个整数时,指针并非简单的加上或减去该整数值,而是加上或减去该整数与指针指向的对象的大小的乘积。例如:inta[10],*p=a;则p=p+1;使指针变量的值更新为数组元素a[1]的地址,即p指向了数组元素a[1]。16注意:a++是错误的,为什么呢?例如:inta[10],*p=a,*q,x;假定数组a的起始地址为2000,则下列每个操作后变量的值分别为多少?三、数组与指针p=p+1;q=p;q+=2;x=q-p;p++;++p;--p;p的值为2002,p指向数组元素a[1].q的值为2002,q指向数组元素a[1].q的值为2006,q指向数组元素a[3].x的值为4p的值为2004,p指向数组元素a[2].p的值为2006,p指向数组元素a[3].p的值为2004,p指向数组元素a[2].p--;p的值为2002,p指向数组元素a[1].通过--运算,让指针变量指向数组中的上一个元素。得到:从数组元素p到q相距字节数通过++运算,让指针变量指向数组中的下一个元素。指针的算术运算除了用于数组外没有什么意义17三、数组与指针5.指针和数组的关系C语言中数组与指针关系密切,它们几乎可以互换。数组名可认为是一个常量指针,指针可以完成涉及数组下标的操作。例如:inta[10],*p=a;则,p指向数组的第一个元素,可用如下的指针表达式引用数组元素a[3]

*(p+3)

式中的3是对于指针变量p的偏移量。当p指向数组的起始位置时,偏移量等于数组的下标。*(p+3)这种表示法称为“指针表示法”(或*(a+3))因为*的优先级高于+,所以圆括号是必需的。注意总结至此,引用一个数组元素,可以采用如下两种方法之一:(1)下标法:如a[i](2)指针法:如*(p+i)或*(a+i)18三、数组与指针例:输出数组中的全部元素。(采用三种方法输出数组元素的值)

#include<stdio.h>

voidmain()

{inta[10],i;

for(i=0;i<10;i++)

scanf("%d",&a[i]);

for(i=0;i<10;i++)

printf("%d",a[i]);

}

#include<stdio.h>

voidmain()

{inta[10],i;

for(i=0;i<10;i++)

scanf("%d",&a[i]);

for(i=0;i<10;i++)

printf("%d",*(a+i)

);

}

#include<stdio.h>

voidmain()

{inta[10],i,

*p;

for(i=0;i<10;i++)scanf("%d",&a[i]);

for(p=a;p<(a+10);p++)

printf("%d",*p);

}1.下标法2.通过数组名计算数组元素的地址,找出元素的值3.用指针变量指向数组元素(例8-6/7)(1)用下标法直观;(2)用前两种方法效率一样;C编译系统是将a[i]转换为*(a+i)来处理的(3)用第三种方法省时间,p++操作快。19三、数组与指针6.用数组名作函数的参数(1)实参数组名代表该数组首元素的地址。而形参是用来接收从实参传递过来的数组首元素的地址。因此,形参应该是一个指针变量(只有指针变量才能存放地址)。(2)虽然函数f的原型为voidf(intarr[],intn),但编译时是将形参数组名arr按指针变量来处理的。即:voidf(intarr[],intn)voidf(int*arr,intn)等价

#include<stdio.h>

voidmain()

{intarray[10];

...

f(array,10);

...

}

voidf(intarr[],intn)

{......}首先回顾上一章“函数”中介绍的数组名作函数参数的情形:说明:如果形参数组中元素的值发生变化,实参数组元素的值随之变化。说明P225:20三、数组与指针例.将数组a中n个元素按相反的顺序存放。(例8-8)

#include<stdio.h>

voidinv(intx[],intn)

//形参为指针变量(*x)??

{inttemp,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;}

return;

}

voidmain()

{inti,a[10]={3,7,9,11,0,6,7,5,4,2};

for(i=0;i<10;i++)printf("%d",a[i]);

inv(a,10);

/*函数调用,实参为数组名*/

for(i=0;i<10;i++)printf("%d",a[i]);}

37

911

0

6

7

5

4

2a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a数组i,xp=x+mj21三、数组与指针例.用选择法对10个整数按由小到大顺序排序。(例8-9)

#include<stdio.h>

voidsort(int*x,intn)

/*形参为指针变量,x[]也可*/

{inti,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;}}

}

voidmain()

{int*p,i,a[10];

p=a;

for(i=0;i<10;i++,p++)scanf(“%d”,p);

p=a;/*思考??*/sort(p,10);

/*函数调用,实参为指针变量*/

for(i=0;i<10;i++,p++)printf("%d",*p);}

a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a数组x22

在C程序中,用两种方法访问字符串:

(1)用字符数组存放一个字符串。

(2)用字符指针指向一个字符串。1.字符串的表示形式

四、字符串与指针

#include<stdio.h>

voidmain()

{charstring[]="china!";

printf("%s\n",string);}

#include<stdio.h>

voidmain()

{char*string="china!";

printf("%s\n",string);}(1)用字符数组存放一个字符串。(2)用字符指针指向一个字符串。用字符串常量初始化字符指针用字符串常量初始化字符数组char*string="china!"char*string;string="china!”;注意:23四、字符串与指针2.访问字符串中的字符

#include<stdio.h>

voidmain()

{chara[]="Ilovechina!",b[20];

inti;

for(i=0;*(a+i)!='\0';i++)

*(b+i)=*(a+i);

*(b+i)='\0';

printf("%s\n",b);}例.将字符串a复制为字符串b。(例8-11)

用指针变量改写见P232例8-12243.字符指针作函数参数

四、字符串与指针

#include<stdio.h>

voidcopy_string(char*from,char*to)

{

for(;*from!='\0';from++,to++)

*to=*from;

*to='\0';

}voidmain()

{char*a="Iamateacher",b[20];

char*p=b;

copy_string(a,p);

printf("%s\n",b);}例.用函数调用实现字符串a复制。(例8-13)

此循环可改为:

while((*to=*from)!='\0')

{to++;from++;}课后:1)理解P236页7点说明2)自学例8-1425五、多维数组的指针1.多维数组元素的地址inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};1357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指针列指针a第0行首地址a+1,&a[1]第1行首地址a[1],*(a+1)第1行第0列元素地址a[1]+2,*(a+1)+2,&a[1][2]第1行第2列元素地址*(a[1]+2),*(*(a+1)+2),a[1][2]第1行第2列元素的值行指针每加1,走一行列指针每加1,走一列26例:

二维数组的有关数据(地址和值)intmain(){inta[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));27五、多维数组的指针(续)2.指向多维数组元素的指针变量

main(){

inta[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);}}(1)指向数组元素的指针变量(2)指向由m个元素组成的一维数组的指针变量

逐个访问各元素时用此类指针

main(){

inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

int(*p)[4],i,j;p=a;printf(“enterrowandcolum:");scanf(“%d,%d”,&i,&j);printf(“a[%d,%d]=%d\n”,i,j,*(*(p+i)+j));}行指针a[i][j]28六、指向函数的指针指向函数的指针变量,用来存放某一函数的起始地址,这意味着此指针变量指向该函数。int(*p)(int,int);p是指向函数的指针变量,它可以指向类型为整型且有两个整型参数的函数。p=max;//把max函数的入口地址赋给了指针变量p如果要用指针调用函数,必须先使指针变量指向该函数:用函数指针变量调用函数时,只需将(*p)代替函数名即可:c=(*p)(a,b);c=max(a,b);因此,指向函数的指针变量的重要用途是:把函数的入口地址作为实参传递给函数的形参,此时形参是指向函数的指针变量,这样就能够在被调用的函数中使用实参函数。main(){inta=3,b=4,c,n;scanf(“%d”,&n);if(n==1)c=fun(a,b,max);elsec=fun(a,b,min);}intfun(int

温馨提示

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

评论

0/150

提交评论