C语言第十章指针的课件.ppt
《C语言第十章指针的课件.ppt》由会员分享,可在线阅读,更多相关《C语言第十章指针的课件.ppt(128页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第十章第十章10.1地址和指针的概念地址和指针的概念10.2变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量10.3数组与指针数组与指针10.4字符串与指针字符串与指针10.5指向函数的指针指向函数的指针10.6返回指针值的函数返回指针值的函数10.7指针数组和指向指针的指针指针数组和指向指针的指针10.8有关指针的数据类型和指针运算的小结有关指针的数据类型和指针运算的小结10.110.1地址和指针的概念地址和指针的概念为了说清楚什么是指针,必须弄清楚数据在内存中是为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。如何存储的,又是如何读取的。内存区的每一个字
2、节有一个编号,这就是内存区的每一个字节有一个编号,这就是“地址地址”。如果在程序中定义了一个变量,系统就会给这个变。如果在程序中定义了一个变量,系统就会给这个变量分配内存单元。量分配内存单元。i i200020003 3直接访问直接访问:、按变量地址、按变量地址(即变量名)(即变量名)存取变量值的方式称存取变量值的方式称为为“直接访问直接访问”方式。方式。(,),);(,);,);例如:例如:2、另一种存取变量值的方式称为、另一种存取变量值的方式称为“间接访问间接访问”的方的方式。将变量的地址放在另一个内存单元中,先到另一式。将变量的地址放在另一个内存单元中,先到另一个内存单元中取得变量的地址
3、,再由变量的地址找到个内存单元中取得变量的地址,再由变量的地址找到变量并进行数据存取。变量并进行数据存取。3 3i200020002000i_pointeri_pointer间接访问方式示意图间接访问方式示意图:在语言中,指针是一种特殊的变量,它是存放地址的。在语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量假设我们定义了一个指针变量i_pointer用来存放整型变用来存放整型变量的地址,它被分配地址为量的地址,它被分配地址为(3010)、(3011)的两个字节。的两个字节。可以通过语句:可以通过语句:i_pointer;将的地址将的地址(2000)存放到存放到i_po
4、inter中。这时,中。这时,i_pointer的值就是的值就是(2000),即变量所占用单元的起始地址。,即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放要存取变量的值,可以采用间接方式:先找到存放“的地址的地址”的变量的变量i_pointer,从中取出的地址,从中取出的地址(2000),然后到,然后到2000、2001字节取出的值()。字节取出的值()。一个变量的地址称为该变量的一个变量的地址称为该变量的“指针指针”。例如,地址例如,地址2000是变量的指针。是变量的指针。如果有一个变量专如果有一个变量专门用来存放另一变量的地址(即指针),则它称为门用来存放另一变量
5、的地址(即指针),则它称为“指针变量指针变量”。上述的。上述的i_pointer就是一个指针变量。就是一个指针变量。指针和指针变量的定义:指针和指针变量的定义:指针变量的值(即指针变量中存放的值)是地址(即指针变量的值(即指针变量中存放的值)是地址(即指针)。请区分指针)。请区分“指针指针”和和“指针变量指针变量”这两个概念。这两个概念。10.2 10.2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量变量的指针变量的指针:就是变量的地址。:就是变量的地址。指针变量指针变量:存放变量地址的变量,用来指向另一个变量。:存放变量地址的变量,用来指向另一个变量。为了表示指针变量和它所指
6、向的变量之间的联系,为了表示指针变量和它所指向的变量之间的联系,在程序中用在程序中用“*”符号表示符号表示“指向指向”。例如:。例如:i-pointer 代表指针变量代表指针变量*i-pointer是是i-pointer所指向的变量,见下图。所指向的变量,见下图。可以看到,可以看到,*i-pointer也代表一个变量,它和变量也代表一个变量,它和变量i是同一回事。下面两个语句作用相同:是同一回事。下面两个语句作用相同:i=3;*i-pointer=3;例如:int i,j;int*pointer_1,*pointer_2;可以用赋值语句使一个指针变量得到另一个变量的地可以用赋值语句使一个指针变
7、量得到另一个变量的地址,从而使它指向一个该变量。如:址,从而使它指向一个该变量。如:pointer_;pointer_;10.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为:基类型基类型 *指针变量名;指针变量名;在定义指针变量时要注意两点:在定义指针变量时要注意两点:(1)指针变量前面的指针变量前面的“*”,表示该变量的类型为指针型,表示该变量的类型为指针型变量。变量。(2)例例:float *pointer_1;(3)指针变量名是指针变量名是pointer_1,而不是,而不是*pointer_1。(4)(2)在定义指针变量时必须指定基类型。在定义指针变量时必须指定基类型。(5
8、)需要特别注意的是,只有整型变量的地址才能放到需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的指向整型变量的指针变量中。下面的赋值是错误的(6)float a;(7)int *pointer_1;(8)pointer_1=&a;10.指针变量的引用指针变量的引用 请牢记,指针变量中只能存放地址(指针),请牢记,指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)不要将一个整数(或任何其他非地址类型的数据)赋给一个指针变量。赋给一个指针变量。下面的赋值是非法的:下面的赋值是非法的:pointer-1=100;(pointer-1为指
9、针变量,100为整数)两个相关的运算符:两个相关的运算符:(1)&:取地址运算符。取地址运算符。(2)*:指针运算符。指针运算符。例如:例如:&a为变量为变量a的地址,的地址,*p为指针变量为指针变量p所指向的所指向的存储单元的内容(即存储单元的内容(即p所指向的变量的值)。所指向的变量的值)。例例10.通过指针变量访问整型变量通过指针变量访问整型变量#include voidmain()int,;,;int*pointer_,*pointer_;pointer_1=a;/*把变量的地址赋给pointer_1*/pointer_2=b;/*把变量的地址赋给pointer_2*/printf(%
10、,%,););printf(%,%,*pointer_1,*pointer_2););对对“”和和“*”运算符说明:运算符说明:如果已执行了语句如果已执行了语句 pointer_;(1)*pointer_的含义是什么?的含义是什么?(2)*的含义是什么?的含义是什么?(3)(*pointer_)相当于什么?)相当于什么?相当于相当于a,即变量,即变量a的地址。的地址。相当于相当于a。相当于。相当于。例例10.2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main()()int*1,*2,*,;,;scanf(,);,);1;2
11、;if()();printf(=,=,););printf(max=,min=,*1,*2););运行情况如下:运行情况如下:,交换前交换前 交换后交换后10.2.3 指针变量作为函数参数指针变量作为函数参数例例10.3 对输入的两个整数按大小顺序输出对输入的两个整数按大小顺序输出#include void main()()void swap(int*,int*);int,;,;int*pointer_,*pointer_;scanf(,);,);pointer_;pointer_2;if()()swap(pointer_,pointer_2););printf(,);,);void swap
12、(int*,int*)int temp;temp*1;*1*2;*2temp;运行情况如下:运行情况如下:5,9 9,5void swap(int*,int*)int temp;temp*1;*1*2;*2temp;int*temp;*temp*1;*1*2;*2*temp;void swap(int*,int*)int temp;temp*1;*1*2;*2temp;int*p;pp1;p1p2;p2p;调用函数不可能改变实参指针变量的值,但可调用函数不可能改变实参指针变量的值,但可以改变实参指针变量所指变量的值。以改变实参指针变量所指变量的值。例例10.输入、输入、3个整数,按大小顺序输出
13、个整数,按大小顺序输出#include void main()()void exchange(int*1,int*2,int*3);int ,*,*,*;scanf(%,%,%,&,&,&););exchange(,);(,);printf(,););void exchange(int*,int*,int*)void swap(int*,int*);if(*)swap(,);(,);if(*)swap(,);(,);if(*)swap(,);(,);void swap(int*pt1,int*pt2)int temp;temp*pt1;*pt1*pt2;*pt2temp;10.3 10.3 数
14、组与指针数组与指针 指针变量可以指向变量,当然也可以指向数组元指针变量可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。素(把某一元素的地址放到一个指针变量中)。所谓所谓数组元素的指针就是数组元素的地址数组元素的指针就是数组元素的地址。定义一个指向数组元素的指针变量的方法,与以定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:前介绍的指向变量的指针变量相同。例如:int int 1010;intint*;10.3.1 10.3.1 指向数组元素的指针指向数组元素的指针对该指针变量赋值:对该指针变量赋值:;把元素的地址赋给指针变量。也就是使
15、把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:指向数组的第号元素,如图:p=&a0;等价于等价于 p=a;10.通过指针引用数组元素通过指针引用数组元素C C规定:规定:如果指针变量如果指针变量p p已指向数组中的一个元素,则已指向数组中的一个元素,则p+1p+1指向同一数组中的下一个元素指向同一数组中的下一个元素(而不是将而不是将p p值简单值简单地加地加1)1)。p+1p+1所代表的地址实际上是所代表的地址实际上是p+1dp+1d,d d是一个数组元素是一个数组元素所占的字节数所占的字节数(对整型,对整型,d=2d=2;对实型,;对实型,d=4d=4;对字符;对字符型,型,d
16、=1)d=1)。图图10.13如果如果p p的初值为的初值为&a0&a0,则:,则:(1)p+i(1)p+i和和a+ia+i就是就是aiai的地址,指向的地址,指向a a数组的第数组的第i i个元个元素,见图素,见图10.1310.13。a a代表数组首地址,代表数组首地址,a+ia+i也是地址,它的计算方法同也是地址,它的计算方法同p+ip+i,即它的实际地址为,即它的实际地址为a+ida+id。例如,。例如,p+9p+9和和a+9a+9的的值是值是&a9&a9,指向,指向a9a9。(2)*(p+i)(2)*(p+i)或或*(a+i)*(a+i)是是p+ip+i或或a+ia+i所指向的数组元
17、素,所指向的数组元素,即即aiai。实际上,在编译时,对数组元素实际上,在编译时,对数组元素aiai就是处理成就是处理成*(a+i)*(a+i),即按数组首地址加上相对位移量得到要找的,即按数组首地址加上相对位移量得到要找的元素的地址,然后找出该单元中的内容。元素的地址,然后找出该单元中的内容。(3)指向数组的指针变量也可以带下标,如指向数组的指针变量也可以带下标,如pi与与*(p+i)等价。等价。引用一个数组元素,可以用:引用一个数组元素,可以用:()()下标法,如形式;下标法,如形式;()()指针法,如指针法,如*()或()或*()()。其中是数组名,是指向数组元素的指针变量,其初其中是数
18、组名,是指向数组元素的指针变量,其初值。值。例例10.5 输出数组中的全部元素输出数组中的全部元素 假设有一个数组,整型,有个元素。要输出假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:各元素的值有三种方法:(1)下标法下标法#include void main()()int;int;for(;)(;)scanf(,);,);printf(););for(;)(;)printf(,);,);(2)通过数组名计算数组元素地址,找出元素的值。通过数组名计算数组元素地址,找出元素的值。#include voidmain()()int;int;for(;(;)scanf(,);,);pri
19、ntf(););for(;)(;)printf(,*();();(3)用指针变量指向数组元素。用指针变量指向数组元素。#include void main()()int;int *,;,;for(;)(;)scanf(,);,);printf(););for(;();)(;();)printf(,*););注意:注意:(1)可以改变指针变量的值。可以改变指针变量的值。例如,上述第例如,上述第(3)(3)种方法是用指针变量种方法是用指针变量p p来指向元素,来指向元素,用用p+p+使使p p的值不断改变,这是合法的。的值不断改变,这是合法的。如果不用如果不用p p而使而使a a变化变化(例如,用
20、例如,用a+)a+)for(p=a;a for(p=a;a(p+10);(p+10);a+a+)printf(%d printf(%d,*a);*a);是不行的。因为是不行的。因为a a是数组名,它是数组首地址,它是数组名,它是数组首地址,它的值在程序运行期间是固定不变的,是常量。的值在程序运行期间是固定不变的,是常量。a+a+是无法实现的。是无法实现的。(2)要注意指针变量的当前值。要注意指针变量的当前值。请看下面的程序。请看下面的程序。例例10.通过指针变量输出数组的个元素。通过指针变量输出数组的个元素。#include void main()()int*,;,;for(;(;)scanf
21、(,);,);printf(););for(;,(;,)printf(,*););printf(););我们先看一下运行情况:1 2 3 4 5 6 7 8 9 022153 234 0 0 30036 25202 11631 8259 8237 28483显然输出的数值并不是数组中各元素的值显然输出的数值并不是数组中各元素的值 解决这个问题的办法,只要在第二个循环之前解决这个问题的办法,只要在第二个循环之前加一个赋值语句:加一个赋值语句:;#include void main()()int*,;,;for(;)(;)scanf(,);,);printf(););p=a;for(;,(;,)p
22、rintf(,*););printf(););(3)指针变量的运算指针变量的运算。先使。先使p指向数组指向数组a(即即p=a),则:,则:p+(或或p+=1),使,使p指向下一元素指向下一元素a1。*p+:等价于:等价于*(p+)。先得到。先得到p指向的变量的值指向的变量的值(即即*p,即,即a0),再使,再使p+1=p。*(p+):先取:先取*p,即,即a0,再使,再使p+1=p。*(+p):先使先使p+1=p,再取,再取*p,即,即a1。(*p)+:表示:表示p所指向的元素值加所指向的元素值加1,即,即(a0)+。10.3.3 用数组名作函数参数用数组名作函数参数在第在第8章章8.7节中介
23、绍过可以用数组名作函数的参数节中介绍过可以用数组名作函数的参数如:void main()void f(int arr,int n);int array 10;f(array,10);void(int arr,int n)void f(int arr,int n)在编译时是将在编译时是将arr按指针变量处理的,相当于将函数按指针变量处理的,相当于将函数f的首部写成的首部写成void f(int*arr,int n)因此,因此,arri和和*(arr+i)等价。等价。实参数组名代表该数组首元素的地址,而形参是用来实参数组名代表该数组首元素的地址,而形参是用来接收从实参传递过来的数组首元素地址的。因
24、此,形接收从实参传递过来的数组首元素地址的。因此,形参应该是一个指针变量。实际上,参应该是一个指针变量。实际上,C编译都是将形参编译都是将形参数组名作为指针变量来处理的。数组名作为指针变量来处理的。例例10 将数组中个整数按相反顺序存放将数组中个整数按相反顺序存放#include void main()()void inv(int ,int);int,10,;,;printf(The original array:););for(;)(;)printf(,);,);printf(););inv(,);(,);printf(The array has been in verted:););for
25、(;)(;)printf(,);,);printf(););void inv(int ,int)/*/*形参形参形参形参x x是数组名是数组名是数组名是数组名*/*/int temp,();,();for(;)(;);temp;temp;return;运行情况如下:The original array:,The array has been inverted:,#include void main()()void inv(int*,int);int,;,;printf(The original array:););for(;)(;)printf(,);,);printf(););inv(,);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 第十 指针 课件
限制150内