C语言程序设计第八章 指针的使用Word格式文档下载.docx

上传人:b****1 文档编号:873450 上传时间:2023-04-29 格式:DOCX 页数:22 大小:142.64KB
下载 相关 举报
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第1页
第1页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第2页
第2页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第3页
第3页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第4页
第4页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第5页
第5页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第6页
第6页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第7页
第7页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第8页
第8页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第9页
第9页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第10页
第10页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第11页
第11页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第12页
第12页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第13页
第13页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第14页
第14页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第15页
第15页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第16页
第16页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第17页
第17页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第18页
第18页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第19页
第19页 / 共22页
C语言程序设计第八章 指针的使用Word格式文档下载.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

C语言程序设计第八章 指针的使用Word格式文档下载.docx

《C语言程序设计第八章 指针的使用Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C语言程序设计第八章 指针的使用Word格式文档下载.docx(22页珍藏版)》请在冰点文库上搜索。

C语言程序设计第八章 指针的使用Word格式文档下载.docx

如果将变量的地址保存在内存的特定区域,用变量来存放这些地址,这样的变量就是指针变量,通过指针对所指向变量的访问,也就是一种对变量的“间接访问”。

指针是什么呢?

可以看作是内存中的一个地址。

这个地址是内存中另一个变量的位置。

在图8-2中,变量x的地址是2000H,就可以称为x的“指针”。

知识链接—变量的直接访问和间接访问

在C语言中,访问变量的值有两种方式——直接访问和间接访问

变量的“直接访问”方式:

按变量名(即变量的地址)存取变量值的方式。

比如在图8-3中直接访问x。

变量的“间接访问”方式:

将变量的地址放在另一个内存单元中,先到另一个内存单元中取得变量的地址,再由变量的地址找到变量并进行数据存取。

比如在图8-3中直接访问p。

图8-3直接访问和间接访问

8.2指针变量的定义与引用

8.2.1指针变量的定义和赋值

1.定义

指针变量的定义格式如下:

类型说明*变量名

其中“*”表示这是个指针变量,变量名表示定义的指针变量的名称,类型说明表示指针变量所指向的变量的数据类型。

例如:

int*p;

表示定义了一个名称为p的指针变量(注意变量名不是*p),它指向的变量的数据类型是int。

2.赋值

指针变量和普通变量一样,使用之前必须赋值,未经赋值的指针变量不可使用。

给指针变量只能给它赋值地址,而不能赋予任何其他数据。

C语言中提供了地址运算符“&

”来表示变量的地址,其一般形式为:

变量名

比如&

x表示变量x的地址。

指针变量的赋值可以按下面的方式:

1int*p;

2intx=5;

3p=&

x;

4printf("

%d\n"

*p);

试一试

(一):

将上面的3行代码改成:

p=x;

能通过编译吗?

运行结果是什么?

【说明】

编译时会出现警告:

'

int*'

differsinlevelsofindirectionfrom'

int'

,意思是int*(p变量的数据类型)和int(x变量的数据类型)不匹配。

运行结果会报错,如图8-4所示:

图8-4指针变量p初始化错误1

从上面的错误可以看出,整数5被编译器当作了地址(0x00000005)。

而当第4行输出p指向的变量的值,报出不能读取的错误,因为0x00000005不是本程序分配的地址。

所以从安全性方面的考虑,会不允许这个读取操作。

试一试

(二):

将第3行代码改成:

*p=x;

编译时会出现警告:

localvariable'

p'

usedwithouthavingbeeninitialized。

意思是变量p在使用前没有初始化。

显然,*p=x这条语句只给*p赋了值,而并没有给变量p赋值。

运行后会报错,如图8-5所示。

图8-5指针变量p初始化错误2

这是因为指针变量p没有赋初值,所以它指向的是一个系统给的不知名的地址(在这次执行时系统分配的是0xcccccccc),虽然p的空间本程序有控制权,但是地址0xcccccccc本程序并没有控制权。

出于安全性考虑,系统禁止向这个地址写入值(*p=x),所以报错。

试一试(三):

下面的代码编译会有问题吗?

1int*p;

2doublex=5.0;

【说明】第1行定义了指针变量p,它指向的变量的数据类型为int。

而在第3行给它赋的值是一个double型的地址。

所以会报警告:

incompatibletypes-from'

double*'

to'

8.2.2指针变量的引用

1.指针变量的引用

引用指针变量,是提供对变量的一种间接访问形式。

对指针变量的引用形式为:

*指针变量

其含义是指针变量所指向的值。

【课堂案例8-1】接收键盘输入的一个小数,用指针的方法将这个数输出。

【案例目标】会使用指针变量实现输出。

【案例知识要点】指针变量的定义、指针变量的赋值、指针的引用。

【案例程序代码】pointRef.c

1#include<

stdio.h>

2

3intmain()

4{

5float*p1;

6floatx;

7scanf("

%f"

x);

8p1=&

9printf("

输入的小数是:

%f\n"

*p1);

10return0;

11}

【程序输出】

图8-6pointRef.exe执行结果

【程序说明】

●第5行定义了指针变量p1,它指向的变量的数据类型是浮点型。

●第8行将浮点型变量x的地址赋给指针变量p1。

●第9行用指针的方法输出。

2.“&

”和“*”运算符

前面用到了“&

”和“*”运算符。

现在总结一下:

“&

”运算符是一个返回操作数地址的单目运算符,称为取地址运算符。

p1=&

就是将变量x的内存地址赋给p1。

“*”运算符称为指针运算符,作用是返回指定内存中的变量值。

例如上面程序中的p1中装有变量x的地址,则:

y=*p1;

就是将变量x的值赋给y。

若x的值是1.0,则y的值也是1.0。

下面通过案例8-2来深入了解指针的使用。

【课堂案例8-2】创建程序sort.c,使用指针实现:

接收从键盘输入两个整数,按由大到小的顺序输出。

【案例目标】指针的综合运用。

【案例知识要点】&

运算符、*运算符、指针变量的定义和使用。

【案例程序代码】swap.c

1#include<

5int*p1,*p2,x,y,t;

/*定义指针变量与整型变量*/

6

7scanf("

%d,%d"

y);

8p1=&

/*使指针变量指向整型变量*/

9p2=&

y;

10

11if(*p1<

*p2)

12{

13t=*p1;

14*p1=*p2;

15*p2=t;

16}

17printf("

%d,%d\n"

x,y);

18return0;

19}

●执行完第9行代码后,内存中指针与变量的关系如图8-7(假定输入的是10,15)。

●第11行的表达式如果为真,则表示第1个数小于第2个数,会执行12~16行的代码。

●第15行执行完毕后,内存中指针与变量的关系如图8-8。

注意:

在程序的运行过程中,指针变量所指向的变量始终没变。

即*p1始终代表x,*p2始终代表y。

改变的只是变量x和y所在内存里的内容。

试一试(四):

将sort.c中的代码修改成sort1.c,如下:

5int*p1,*p2,a,b,*t;

//t被定义为指针变量

6scanf("

a,&

b);

7p1=&

a;

8p2=&

b;

9

10if(*p1<

11{

12t=p1;

13p1=p2;

14p2=t;

15}

16printf("

*p1,*p2);

17return0;

18}

结果会相同吗?

【说明】程序运行结果是完全相同的。

但程序在运行过程中,实际存放在内存中的数据没有移动,而是将指向该变量的指针交换了指向。

如图8-9右所示:

图8-9sort1.exe执行后内存图

当指针交换指向后,p1和p2由原来指向的变量x和y改变为指向变量y和x,这样一来,*p1就表示变量y,而*p2就表示变量x。

在上述程序中,无论在何时,只要指针与所指向的变量满足p=&

x;

我们就可以对变量x以指针的形式来表示。

此时p等效于&

x,*p等效于变量x。

8.3数组与指针

8.3.1指针的自加自减运算

假定定义了指针变量p,对它做“加1”运算,不是简单地将p的值加上1,而是将p的值加上1倍的它所指向的变量占用的内存字节数。

指针加i(即p+=i)是将p的值加上i倍的它所指向变量占用的内存字节数。

对于int型变量,它占用内存的字节数为4,因此,p++后p的值增加4,如图8-10所示。

图8-10p++后的内存图

8.3.2使用指针访问一维数组

假设我们定义一个一维数组,该数组在内存会有系统分配的一个存储空间,其数组的名

字就是数组在内存的首地址。

若再定义一个指针变量,并将数组的首址传给指针变量,则该

指针就指向了这个一维数组。

我们说数组名是数组的首地址,也就是数组的指针。

而定义的

指针变量就是指向该数组的指针变量。

对一维数组的引用,既可以用传统的数组元素的下标

法,也可使用指针的表示方法。

1int*p,a[5];

2p=a;

这里a是数组名,也代表数组的首地址,所以可以将它赋值给指针变量p。

知识链接—认识数组名

一维数组名是个指针常量,它存放的是一维数组第一个元素的地址。

常量是不能被改变的,也就是说,一维数组名是不能被改变的。

数组名a存放的是一维数组第一个元素的地址,也就是a=&

a。

也就说把a数组的内容以十六进制和把a数组元素的第一个值的地址输出是一样的。

由于a[0]的地址就是数组的首地址,所以下面的语句和上面的等价。

2p=&

a[0];

C语言中指针对数组的表示方法有下面几种:

●p+n与a+n表示数组元素a[n]的地址,即&

a[n]。

对整个a数组来说,共有5个元素,n的取值为0~4,则数组元素的地址就可以表示为p+0~p+4或a+0~a+4,与&

a[0]~&

a[4]保持一致。

●知道了数组元素的地址表示方法,*(p+n)和*(a+n)就表示为数组的各元素即等效于a[n]。

●指向数组的指针变量也可用数组的下标形式表示为p[n],其效果相当于*(p+n)。

下面用【课堂案例8-3】来具体说明。

【课堂案例8-3】定义一个长度为5的数组,以数组的不同引用形式输出数组各元素的值。

【案例目标】会使用指针访问数组元素。

【案例知识要点】指针变量表示的地址法访问数组元素、数组名表示的地址法访问数组元素、指针表示的下标法访问数组元素、指针法访问数组元素。

【案例程序代码】pointArray.c

5inta[5]={1,2,3,4,5};

6int*p;

7

8p=a;

10printf("

*(p+1));

11printf("

*(a+1));

12printf("

a[1]);

13printf("

p[1]);

14

15return0;

16}

图8-11pointArray.exe执行后内存图

●第8行:

给指针变量p赋值了数组a的首地址。

●第9行:

最开始p指向数组的首地址,即第一个元素的地址,所以*p输出数组的第1个元素。

●第10行:

采用指针变量表示的地址法输出数组第2个元素。

因为p+1表示数组元素a[1]的地址。

所以*(p+1)表示a[1]的值。

●第11行:

采用数组名表示的地址法输出数组第2个元素。

因为a表示的是数组的第1个元素的地址,a+1表示的是第2个元素的地址。

所以*(a+1)表示a[1]的值。

●第12行:

普通的数组下标法输出第2个元素。

●第13行:

采用指针表示的下标法输出第2个元素。

8.3.3使用指针访问二维数组

定义一个二维数组:

inta[2][3];

表示二维数组有2行3列共6个元素,在内存中按行存放,存放形式为图8-11:

图8-11二维数组在内存中的存放

其中a是二维数组的首地址,&

a[0][0]既可以看作数组第1行第1列的首地址,同样还可以看作是二维数组的首地址,a[0]是第1行的首地址,也是这个一维数组的首地址。

同理a[n]就是第n+1行的首址;

a[n][m]就是数组元素a[n][m]的地址。

既然二维数组每行的首地址都可以用a[n]来表示,我们就可以把二维数组看成是由n行一维数组构成,将每行的首地址传递给指针变量,行中的其余元素均可以由指针来表示。

用地址法来表示数组各元素的地址。

对元素a[0][1],&

a[0][1]是其地址,a[0]+1也是其地址(可参考8-12来理解)。

分析a[0]+1与a[0]+2的地址关系,它们地址的差并非整数1,而是一个数组元素的所占位置4,原因是每个数组元素占4个字节。

图8-12指针和二维数组的关系

下面用【课堂案例8-4】来具体说明。

【课堂案例8-4】定义一个2行3列的二维数组,以数组的不同引用形式输出数组各元素的值。

【案例目标】会使用指针访问二维数组元素。

【案例知识要点】二维数组元素不同的访问方式。

【案例程序代码】pointTwoDemArray.c

5inta[2][3]={{1,2,3},{4,5,6}};

8p=a[0];

%x,%x,%x\n"

a,a[0],&

a[0][0]);

*(a[0]+2));

*(a[1]));

14

图8-13pointTwoDemArray.exe执行结果

输出了三个变量的值,a、a[0]、&

a[0][0]都表示二维数组的首地址,所以三个值相同。

因为给p赋的值是数组首地址,而就是第1个元素的值,所以相当于输出a[0][0],即整数1。

p+1表示将指针下移了一个元素,所以输出的是a[0][1],即整数2。

a[0]表示的是第1行第1个元素的地址,a[0]+2表示下移两个元素的地址,相当于&

a[0][2],所以输出的是a[0][2]的值,即整数3。

a[1]表示的是第2行第1个元素的地址,所以输出的是a[1][0]的值,即整数4。

【课堂练习】

求解二维数组中的最大值及该值在二维数组中的位置。

8.3.4指针操作字符串

访问一个字符串可以通过两种方式:

●通过数组名来表示字符串,数组名就是数组的首地址,是字符串的起始地址。

●使用字符指针指向一个字符串,可不定义数组。

对第一种方式,可以将字符数组的名赋予一个指向字符类型的指针变量,让字符类型指针指向字符串在内存的首地址,对字符串的表示就可以用指针实现。

下面的程序介绍了具体用法。

1#include<

2main()

3{

4charc[10];

5char*p;

7p=c;

//p=c则表示将字符数组的首地址传递给指针变量p

8gets(c);

%s\n"

p);

//使用指针变量p输出字符串

10}

下面的程序说明了第二种方式的用法:

5char*str="

这是一个字符串..."

;

6printf("

str);

7return0;

8}

上面程序第5行把一个字符串赋值给指针变量p,实际上只是把字符串中的第1个字符的地址赋值给它。

【课堂案例8-5】

5chars1[]="

c语言是一门基础语言课"

6char*p1,*p2;

7chars2[22];

8

9p1=s1;

10p2=s2;

11

12while(*p1!

='

\0'

13{

14*p2=*p1;

15p1++;

16p2++;

17}

18

19*p2='

20printf("

第二个字符串的内容:

s2);

21return0;

22}

图8-14pointCopyStr.exe执行结果

8.4指针变量作函数的参数

学习了指向一维和二维数组指针变量的定义和正确引用后,我们现在学习用指针变量作

函数的参数。

使用经典的交换两个数的案例来说明。

程序swap.c希望通过定义一个swapNum的函数来交换两个数。

2voidswapNum();

5inta=5;

6intb=10;

7

8printf("

互换前:

a=%d,b=%d\n"

a,b);

9swapNum(a,b);

函数调用完毕-------互换后:

12

13voidswapNum(inta,intb)

14{

15intt;

16t=a;

17a=b;

18b=t;

19printf("

swapNum函数中------互换后:

20return;

21}

程序执行结果如图8-14所示,显然没有互换成功。

因为函数的a,b已经执行完成,分配给内存的空间已经释放了,所以最终a,b的值还是主函数a,b的值。

互换的是形参的a,b。

和主函数没有关系。

图8-14swap.exe执行结果

下面使用指针变量作为参数来完成两个数的互换。

【课堂案例8-5】使用指针变量作为参数来完成两个数的互换。

【案例目标】会使用指针变量做参数。

【案例知识要点】函数的定义、指针变量做函数参数、函数的调用。

【案例程序代码】pointSwap.c

9swapNum(&

b);

13voidswapNum(int*p1,int*p2)

16t=*p1;

17*p1=*p2;

18*p2=t;

*p1,*p2);

图8-15pointSwap.exe执行结果

●第6行执行完毕后变量a、b在内存中的表示如图8-16

(1)所示。

●第9行调用函数swapNum,传递的是a和b的地址。

●第13行定义了swapNum函数,参数是int型的指针类型。

形参分别为p1和p2。

第13行执行完毕后内存中的表示如图8-16

(2)所示。

●执行完第15~18行后,内存中的变化如图8-16(3)所示。

显然,交换了a、b两个变量的内容。

图8-16pointSwap.exe执行结果

1.编写一个函数max,能返回一维数组中的最大元素。

2.编程实现将一个数组中的元素按照相反的顺序存放。

8.4本章小节

本章介绍了C语言中各种流程控制语句的用法。

学习本章后,应该掌握如下内容:

●如何定义指针变量。

●如何给指针变量赋值。

●如何使用指针访问数组。

●如何使用指针操作字符串。

●在函数中使用指针变量做参数

 

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2