《c程序设计 第10章_指针1.ppt》由会员分享,可在线阅读,更多相关《c程序设计 第10章_指针1.ppt(108页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第十章第十章10.110.1地址和指针的概念地址和指针的概念为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。内存区的每一个字节有一个编号,这就是“地址地址”。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。、按变量地址存取变量值的方式称为“直接访问直接访问”方式(,);(,);例如:例如:另一种存取变量值的方式称为“间接访问间接访问”的方式。即,将变量的地址存放在另一个变量中。在语言中,指针是一种特殊的变量,它是存放地址的。在语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量i_pointer用来存放整型变量的地址
2、,它被分配地址为(3010)、(3011)的两个字节。可以通过语句:i_pointer;将的地址(2000)存放到i_pointer中。这时,i_pointer的值就是(2000),即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer,从中取出的地址(2000),然后到2000、200字节取出的值()。一个变量的地址称为该变量的“指针指针”。例如,地址2000是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量指针变量”。上述的i_pointer就是一个指针变量。指针和指针变量的定义:指针和指针变量的定义:指
3、针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针”和“指针变量”这两个概念。10.2 10.2 变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量10.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为基类型基类型 *指针变量名;指针变量名;下面都是合法的定义:float *pointer_;/pointer_是指向float型变量的指针变量char*pointer_;/pointer_是指向字符型变量的指针变量可以用赋值语句使一个可以用赋值语句使一个指针变量得到另一个变指针变量得到另一个变量的地址,从而使它指量的地址,从而使它指向一个该变量。如:向一个该变
4、量。如:pointer_;pointer_;在在定义定义指针变量时要注意两点:指针变量时要注意两点:(1)指针变量前面的“*”,表示该变量的类型为指针型变量。(2)例:float *pointer_1;(3)指针变量名是pointer_1,而不是*pointer_1。(4)(2)在定义指针变量时必须指定基类型。(5)需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的(6)float a;(7)int *pointer_1;(8)pointer_1=&a;/*将float型变量的地址放到指向整型变量的指针变量中,错误*/10.指针变量的引用指针变量的引用 请
5、牢记,指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)赋给一个指针变量。例例10.通过指针变量访问整型变量通过指针变量访问整型变量#include voidmain()int,;int*pointer_,*pointer_;pointer_;/*把变量的地址赋给 pointer_1*/pointer_;/*把变量的地址赋给 pointer_*/printf(%,%,);printf(%,%,*pointer_,*pointer_);对“”和“*”运算符说明:如果已执行了语句 pointer_;(1)*pointer_的含义是什么?“”和“*”两个运算符的优先级别相同
6、,但按自右而左方向结合,因此先进行*pointer_的运算,它就是变量,再执行运算。因此,*pointer_与相同,即变量a的地址。如果有pointer_2*pointer_;它的作用是将(的地址)赋给pointer_2,如果pointer_2原来指向,经过重新赋值后它已不再指向了,而指向了。(2)*的含义是什么?先进行运算,得的地址,再进行*运算。即所指向的变量,也就是变量a。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价。(3)(*pointer_)相当于。注意括号是必要的,如果没有括号,就成为了*pointer_,从附录可知:+和*为同一优先级别,而结合方向为自右而左
7、,因此它相当于*(pointer_)。由于+在pointer_1的右侧,是“后加”,因此先对pointer_的原值进行*运算,得到的值,然后使pointer_的值改变,这样pointer_不再指向了。例例10.2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main()int*1,*2,*,;scanf(,);1;if();printf(=,=,);printf(max=,min=,*1,*2);运行情况如下:运行情况如下:,当输入,时,由于,当输入,时,由于,将和交换。交换前的情况见图将和交换。交换前的情况见图(),交换后见图
8、()。(),交换后见图()。10.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(int*,int*)int temp;temp*1;*;*temp;为了使在函数中改变的变量值为了使在函数中改变的变量值能被能被main函数所用函数所用,应该
9、用应该用指指针变量针变量作为函数参数作为函数参数,在函数在函数执行过程中使指针变量执行过程中使指针变量所指向所指向的变量值的变量值发生变化发生变化,函数调用函数调用结束后结束后,变量值的变化依然保变量值的变化依然保留留,实现了实现了”通过调用函数使通过调用函数使变量的值发生变化变量的值发生变化,在主调函在主调函数中使用这些改变了的值的目数中使用这些改变了的值的目的的”.void swap(int*,int*)int temp;*temp*1;*;*temp;*p1就是a,是整型变量,*temp是指针变量temp所指向的变量.temp并无确定的值,所指向的单元也是不可预见的.应该将*p的值赋给整
10、型变量.错错void swap(int x,int y)int temp;tempx;xy;ytemp;错错执行完swap函数后,x和y的值是互换了,但main函数中的a和b并没有互换,因为”单向传递”的”值传递”方式,形参值的改变无法传给实参.void swap(int*,int*)int *p;p1;p;错错因为形参变量和实参变量之间的数据传递是单向的”值传递”方式,指针变量做函数参数也遵循这一规则.调用函数不可能改变实参指针变量的值,但可以改变实参指针变量所指变量的值.例例10.输入、输入、3个整数,按大小顺序输出个整数,按大小顺序输出#include void main()void e
11、xchange(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*,int*)int temp;temp*;*;*temp;10.3 10.3 数组与指针数组与指针 一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组
12、元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元数组元素的指针就是数组元素的地址素的地址。定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:;(定义为包含个整型数据的数组)*;(定义为指向整型变量的指针变量)应当注意,如果数组为型,则指针变量的基类型亦应为型。10.3.1 10.3.1 指向数组元素的指针指向数组元素的指针对该指针变量赋值:对该指针变量赋值:;把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:C语言中规定数组名代表数组中第一个元素(序号为语言中规定数组名代表数组中第一个元素(序号为的元素)的地址因此下面两个语句等价
13、:的元素)的地址因此下面两个语句等价:p=&a0;p=a;数组名数组名a不代表整个数组不代表整个数组,p=a的作用是把的作用是把a数组的首元数组的首元素的地址赋给指针变量素的地址赋给指针变量p,而不是把数组,而不是把数组a各元素的各元素的值赋给值赋给p在在定义定义的时候,可以对它赋初值:的时候,可以对它赋初值:Int*p=&a0;Int*p=a;如果指针变量如果指针变量p已指向数组中的一个元素,则已指向数组中的一个元素,则p指向指向同一数组中的下一个元素同一数组中的下一个元素P所代表的地址实际上所代表的地址实际上是是p+1d,d是一个数组元素所占的字节数是一个数组元素所占的字节数如果如果p的初
14、值为的初值为a,则,则()()pi和和ai就是就是ai的的地地址,它们指向址,它们指向a数组的第数组的第i个个元素元素如如p和和a的值是的值是a,它指向,它指向a()()(pi)或()或(ai)是)是pi或或ai所指向的数所指向的数组元素,即组元素,即ai如(如(p)或()或(a)就是)就是a即(即(p)()(a)a10.通过指针引用数组元素通过指针引用数组元素引用一个数组元素,可以用:()()下标法,如形式;下标法,如形式;()()指针法,如指针法,如*()或()或*()()。其中是数组名,是指向数组元素的指针变量,其初值。例例10.5 输出数组中的全部元素输出数组中的全部元素 假设有一个数
15、组,整型,有个元素。要输出各元素的值有三种方法:(1)下标法下标法#include void main()int;int;for(;)scanf(,);printf();for(;)printf(,);(2)通过数组名计算数组元素地址,找出元素的值。#include voidmain()int;int;for(;)scanf(,);printf();for(;)printf(,*();(3)用指针变量指向数组元素。#include void main()int;int *,;for(;)scanf(,);printf();for(;();)printf(,*);例例10.通过指针变量输出数组的
16、个元素。通过指针变量输出数组的个元素。有人编写出以下程序:有人编写出以下程序:#include void main()int*,;for(;)scanf(,);printf();for(;,)printf(,*);这个程序乍看起来好像没有什么问题。有的人即使已被告知此程序有问题,还是找不出它有什么问题。我们先看一下运行情况:1 2 3 4 5 6 7 8 9 022153 234 0 0 30036 25202 11631 8259 8237 28483显然输出的数值并不是数组中各元素的值显然输出的数值并不是数组中各元素的值 指针变量的初始值为指针变量的初始值为a的数组首地址的数组首地址,经过
17、第一个for循环读入数据后,p已经指向a数组的末尾,因此,在执行第二个For循环时,p的起始值不是&a0,而是a+10了.解决这个问题的办法,只要在第二个循环之前解决这个问题的办法,只要在第二个循环之前加一个赋值语句:加一个赋值语句:;使使p的初始值回到的初始值回到&a0#include void main()int*,;for(;)scanf(,);printg();p=a;for(;,)printf(,*);指针变量的运算:指针变量的运算:()()p,使使p指向下一个元素,即指向下一个元素,即a()p,由于和同优先级,结合方向自右由于和同优先级,结合方向自右向左,等价于(向左,等价于(p)
18、,作用是先得到),作用是先得到p指向的变指向的变量的值(即量的值(即p),再使),再使pp()()(p)和)和(p)作用不同前者是先作用不同前者是先取取p的值,然后使的值,然后使p后者是先使后者是先使p,再取,再取p若若p初值为初值为a(即(即a),输出(),输出(p)时,)时,得到得到a的值,而输出(的值,而输出(p),则得到),则得到a的值的值()()(p)表示表示p所指向的元素所指向的元素值值加,如加,如a,则(,则(a)的值为)的值为10.3 用数组名作函数参数用数组名作函数参数在第在第8章章8.7节中介绍过可以用数组名作函数的参数节中介绍过可以用数组名作函数的参数如:void mai
19、n()i(int,int);int;(,);void(int,int)arr接收了实参数组接收了实参数组array的首地址后,的首地址后,arr就指向实参数组的首元素就指向实参数组的首元素*arr就是就是array的值的值(arri)等价于)等价于arri在调用函数期间,在调用函数期间,arr,arr,以及,以及array都是数组都是数组array第个元素的值第个元素的值f(int arr,int n)但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成f(int*arr,int n)以上两种写法是等价的。需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当当用用变
20、变量量名名作作为为函函数数参参数数时时传传递递的的是是变变量量的的值值,当当用用数数组组名名作作为为函函数数参参数数时时,由由于于数数组组名名代代表表的的是是数数组组首首元元素素地地址址,因此传递的值是地址,所以要求形参为指针变量,也允许使用形参数组的形式。用数组名做参数时用数组名做参数时,如果形参数组中各元素的值,如果形参数组中各元素的值发生改变,实参数组元素的值随之发生改变发生改变,实参数组元素的值随之发生改变有一个形参数组,它从实参数组那里得到起始地址,因此形参数组和实参数组共同占用同一段内存单元,在调用函数时,如果改变了形参数组的值也就是改变了实参数组的值.常用这种方法调用一个函数来改
21、变实参数组的值.例例10 将数组中个整数按相反顺序存放将数组中个整数按相反顺序存放#include void main()void inv(int ,int);int,;printf(The original array:);for(;)printf(,);printf();inv(,)(,);printf(The array has been in verted:);for(;)printf(,);printf();void inv(int ,int)/*/*形参形参形参形参x x是数组名是数组名是数组名是数组名*/int temp,();for(;);temp;temp;return;运行
22、情况如下:The original array:,The array has been inverted:,#include void main()void inv(int*,int);int,;printf(The original array:);for(;)printf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();对这个程序可以作一些改动。将函对这个程序可以作一些改动。将函数数inv中的形参改成指针变量。中的形参改成指针变量。void inv(int*,int)/*/*
23、形参形参形参形参x x为指针变量为指针变量为指针变量为指针变量*/int*,temp,*,*,();for(;,)emp*;*;*temp;return;形参x为指针变量,实参为数组名a,即数组a首地址,将它传给形参变量x,这时x就指向ai与j交换,就是ai与aj交换 归纳起来,如果有一个实参数组,想在函归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:的对应关系有以下种情况:(1)形参和实参都用数组名,如:形参和实参都用数组名,如:void main()void (int ,int)int;(,);由于形参
24、数组名接收了实参数组首元素的地址,因此由于形参数组名接收了实参数组首元素的地址,因此可以认为在函数调用期间,形参数组与实参数组共用可以认为在函数调用期间,形参数组与实参数组共用一段内存单元一段内存单元(2)实参用数组名,形参用指针变量。如:实参用数组名,形参用指针变量。如:void()void(int*,int)int ;(,);(3)实参形参都用指针变量。例如:实参形参都用指针变量。例如:void main()void(int*,int)int,*p=a;(p,);X指向a,即xaxa先使实参指针变量p指向数组a,p的值是a然后将p的值传给形参指针变量,x的初始值也是a通过x值的改变使x指向
25、数组中的任一元素(4)实参为指针变量,形参为数组名。如:实参为指针变量,形参为数组名。如:void main()void(int x,int),*p=a;(p,);如果用指针变量做实参,如果用指针变量做实参,必须先使指针变必须先使指针变量有确定值,量有确定值,指向一个以及功能定义的单元#include void main()void inv(int*,int);int,*;printf(The original array:n);for(;,)scanf(,);printf();inv(,);/*实参为指针变量实参为指针变量*/printf(The array has been inverte
26、d:);for(;)printf(,*);printf();void inv(int*,int)int,temp,*,*;();for(;,)emp*;*;*temp;return;例例109 用选择法对个整数按由大到小顺序排序用选择法对个整数按由大到小顺序排序#include void main()void sort(int ,int);int*,10;for(;)scanf(,);sort(,);for(,;)(,*);void sort(int ,int)int,;for(;);for(;)();(!);10.多维数组与指针多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多
27、维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。1.多维数组元素的地址多维数组元素的地址先回顾一下多维数组的性质,可以认为二维数组是二维数组是“数数组的数组组的数组”,例:定义定义int a34=1,3,5,7,;则二维数组a是由3个一维数组所组成的。a是一个数组是一个数组名名a数组包含行,即三个元素:数组包含行,即三个元素:a,a,aa代表二维数组首元素的地址代表二维数组首元素的地址,现在的首元素不是一个整型变量,而是有个整型变量组成的一维数组,因此a代表的是首行(第行)的首地址代表的是首行(第行)的首地址(a)代表第行的首地址既)代表第行的首地址既a的首地址的
28、首地址a,a,a既然是一维数组名,也就是这一维数组的首元素地址,因此,a代表一维代表一维数组数组a中第列元素的地址既中第列元素的地址既aa的值是的值是a,a为一维数组名,该一维数组中第二个元素用该一维数组中第二个元素用a来表示来表示a和(和(a)等价)等价,ai和(和(ai)等价)等价(aij)或()或(ai)j)是)是aij的的值值ai的说明:的说明:如果如果a是一维数组名,则是一维数组名,则ai是是a数组数组第第i个元素所占内存单元的个元素所占内存单元的内容内容如果如果a是二维数组,则是二维数组,则ai是代表一维是代表一维数组名,他只是一个数组名,他只是一个地址地址a和(和(a):a是二维
29、素组是二维素组a中第行的首地址中第行的首地址(a)就是)就是a,a是是一维数组名,也是地址,指向一维数组名,也是地址,指向a二维数组名是指向行的一维数组名是指向列的元素的二维数组名是指向行的一维数组名是指向列的元素的在指向行的指针前面加一个,就转换为指向列的指针在指向行的指针前面加一个,就转换为指向列的指针表表 示示 形形 式式含义含义地地 址址a 二维数组名,指向一维数组a0,即0行首地址2000a0,*(a+0),*a0行0列元素地址2000a+1,&a11行首地址2008a1,*(a+1)1行0列元素a10的地址2008a1+2,*(a+1)+2,&a121行2列元素a12 的地址201
30、2*(a1+2),*(*(a+1)+2),a121行2列元素a12的值元素值为13例例10.0 输出二维数组有关的值输出二维数组有关的值#include define FROMAT,void main()int 341,3,5,7,9,;printf(,*);printf(,0,*();printf(,0,00);printf(,1,);printf(,10,*(+)+);printf(,*();printf(,);printf(,*(*();某一次运行结果如下:,(0行首地址和0行0列元素地址),(0行0列元素地址),(0行0首地址和0行0列元素地址),(1行0列元素地址和1行首地址),(1
31、行0列元素地址),(2行0列元素地址),(2行首地址),(1行0列元素的值)2.指向多维数组元素的指针变量指向多维数组元素的指针变量在了解上面的概念后,可以用指针变量指向多维数组的元素。(1)指向指向数组元素数组元素的指针变量的指针变量例例10.11 10.11 用指针变量输出二维数组元素的值用指针变量输出二维数组元素的值#include void main()int 341,3,5,7,9,11,13,15,17,19,21,23;int*;for(;)()printf();printf(,*);运行结果如下:1 3 5 7 9 11 13 1519 21 23 可将程序最后两个语句改为可将
32、程序最后两个语句改为printf(addr,value2,*);在TC+环境下某一次运行时输出如下:,计算计算aij在数组中的相对位置的公式为:在数组中的相对位置的公式为:imj(二维数组大小为(二维数组大小为nm)aij的地址为的地址为aimj例:如果开始时指针变量例:如果开始时指针变量p指向指向a,为,为了得到了得到a的值,可以用(的值,可以用(p)表示()表示(p)是)是a的的地址地址(p是指向整型变量的,是指向整型变量的,p所指向的元所指向的元素是素是p所指向元素的下一元素)所指向元素的下一元素)(2)指向由个元素组成的一维数组的指针变量指向由个元素组成的一维数组的指针变量例例10.1
33、3 10.13 输出二维数组任一行任一列元素的值输出二维数组任一行任一列元素的值#include void main()int 1,3,5,7,9,11,13,15,;int(*),;scanf(,);printf(,*(*();运行情况如下:,(本行为键盘输入),运行情况如下:,(本行为键盘输入),P是指向一个包含是指向一个包含m个元素的一维数组个元素的一维数组如果如果p先指先指向向a,则,则p不是指向不是指向a,而是指向而是指向a,pi是二维数组是二维数组a的第的第i行地址行地址p的增值是以一维数组的长度为单位的增值是以一维数组的长度为单位Int(p)表示表示p是一个指针变量,它指向是一个
34、指针变量,它指向包含个整型元素的一维数组即包含个整型元素的一维数组即p是行指针,是行指针,p的值就是该一维数组的首地址的值就是该一维数组的首地址P不能指向一维不能指向一维数组中的第数组中的第j个元素个元素Intp表示一个指针数组表示一个指针数组3.用指向数组的指针作函数参数用指向数组的指针作函数参数例例10.13 有一个班,个学生,各学门课,计算总有一个班,个学生,各学门课,计算总平均分数以及第个学生的成绩。这个题目是很简单平均分数以及第个学生的成绩。这个题目是很简单的。只是为了说明用指向数组的指针作函数参数而举的。只是为了说明用指向数组的指针作函数参数而举的例子。用函数求总平均成绩,用函的例
35、子。用函数求总平均成绩,用函数找出并输出第个学生的成绩。数找出并输出第个学生的成绩。#include void 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,);*求序号为的学生的成绩*void average(float*,int)float*_;float,;_;(;_;)(*);printf(average,aver);
36、void search(float(*)4,int)/*p是指向具有4个元素的一维数组的指针*/int;printf(the score of No.%are:,);for(;)printf(5.2,*(*();程序运行结果如下:.例例10.4 在上题基础上,查找有一门以上课程不及格的在上题基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程的成绩。学生,打印出他们的全部课程的成绩。#include void main()void search(float(*p)4,int n);/*函数声明*/float score34=65,57,70,60,58,87,90,81,90,99,1
37、00,98;search(score,);void search(float(*p)4,int)int,;for(;)flag;for(;)if(*(*())flag;if()printf(No.%d fails,his scores are:n,j+1);for(;)printf(%.,*(*();printf();程序运行结果如下:s,:.s,.10.10.字符串与指针字符串与指针10字符串的表示形式字符串的表示形式 例例 10.5 定义一个字符数组,对它初始化,定义一个字符数组,对它初始化,然后输出该字符串然后输出该字符串#include void main()char string !
38、;printf(,);(1)用字符数组存放一个字符串,然后输出该字符串。用字符数组存放一个字符串,然后输出该字符串。(2)用字符指针指向一个字符串用字符指针指向一个字符串 可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。例106 定义字符指针#include void main()char *string !;printf(,);C语言中对字符串常量按字符数组处理的char *string !“等价于char*string;string=“I love china!”;string被定义为一个指针变量,只能指向一个字符变量,不能同时指向多个字符数据,是把字符串的第个字符的
39、地址赋值给指针变量string输出时用printf(“%sn”,string);系统先输出字符串指向的第一个字符数据,然后自动使string加,使之指向下一个字符,然后再输出直到遇到字符串结束标志为止例例10.10.7 7 将字符串复制为字符串将字符串复制为字符串 对字符串中字符的存取,可以用下标方法,也可以用指针方法#include void()char am a boy,20;int;for(;*()!;)*()*();*();printf(string a is:,);printf(string is:);for(;!;)printf(,);printf();也可以设指针变量,用它的值的
40、改变来指向字符串中的不同的字符。例例10.8 用指针变量来处理例用指针变量来处理例107问题。问题。#include void main()char =I am a boy.,20,*p1,*p2;int;for(;*!;p1,p2)*;*;printf(string is:,);printf(:);for(;!;)printf(,);printf();程序必须保证使和同步移动。10.字符指针作函数参数字符指针作函数参数例例1019 用函数调用实现字符串的复制用函数调用实现字符串的复制#include void main()void copy_string(char from,char to)
41、;char a=am a teacher;char =you are a student;printf(“string a=string,);printf(copy string a to string b:n);copy_string(,);printf(nstring a=%snstring b=%sn,a,b);(1)用字符数组作参用字符数组作参数数void copy_string(char from,char to)int;while(!);程序运行结果如下:copy string a to string b:()()形参用字符指针变量形参用字符指针变量#include void ma
42、in()void copy_string(char*from,char*to);char*am a teacher.;char*you are a student;printf(“string a=sn string b%sn,a,b);printf(copy string a to string b:n);copy_string(a,b);printf(nstring a=%snstring b=%sn,a,b);void copy_string(char*,char*)for(;*from!;from,to)*;*;()()对对 copy_string 函数还可作简化函数还可作简化 1、将
43、copy_string函数改写为void copy_string(char*,char*)while(*)!);10.对使用字符指针变量和字符数组的讨论对使用字符指针变量和字符数组的讨论虽然用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混为一谈,主要有以下几点:(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1个字符的地址),决不是将字符串放到字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值,不 能用以下办法对字符数组赋值。char str;str !;而对字符指针变量,可以采用下面方法赋值:char*
44、;!;但注意赋给的不是字符,而是字符串第一个元素 的地址。(3)对字符指针变量赋初值:char*love China!;等价于 char*;!;而对数组的初始化:char str love China!;不能等价于 char str;str !;数组可以在定义时整体赋初值,但不能在赋值语句中整体赋值(4)如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。而定义一个字符指针变量时,给指针变量分配内存单元,在其中可以放一个字符变量的地址也就是说,该指针变量可以指向一个字符型数据,但如果未对它赋予一个地址值,则它并未具体指向一个确定的字符数据。如:char str;scanf(,st
45、r););是可以的。而常有人用下面的方法,目的是想输入一个字符串,虽然一般也能运行,但这种方法是危险的:char*;scanf(,);,);应当这样:应当这样:*,;(,);(5)指针变量的值是可以改变的,如:例例10.0改变指针变量的值改变指针变量的值#include void()char*I love China!;printf(,);运行结果:China!指针变量a的值可以改变,输出字符串时从a当时所指的单元开始输出各个字符,直到遇到为止数组名虽然代表地址但它是常量,它的值不能改变charstrI love China!;strstr;printf(,str);错误错误需要说明,若定义了
46、一个指针变量,并使它指向一个字符串,就可以用下标形式引用指针变量所指的字符串中的字符。#include voidmain()char*love hina!;int;printf(“The sixth character is%cn,a5);for(;!;)printf(,);程序中虽未定义数组a,但字符串在内存中是以字符数组形式存放的结果:The sixth character is e love hina!10.10.指针数组和指向指针的指针指针数组和指向指针的指针10.指针数组的概念指针数组的概念一个数组,若其元素均为指针类型数据,称为指针指针数组数组,也就是说,指针数组中的每一个元素都相
47、当于一个指针变量。一维指针数组的定义形式为类型名类型名数组名数组长度;数组名数组长度;int*p4;-一维指针数组一维指针数组Int (*p)4指向一维数组的指针变量指向一维数组的指针变量指针数组适合于用来指向若干个字符串指针数组适合于用来指向若干个字符串例例106 将若干字符串按字母顺序(由小到大)输出。将若干字符串按字母顺序(由小到大)输出。#include#include void main()void sort(char*name,int n);void printf(char*name,int n);char*name=Follow me,BASIC,Great Wall,FORTR
48、AN,Computer design;int;sort(,);print(,);void sort(char*,int)char *;int,;for(;);for(;)if(strcmp(name,name)0)=;if(!)temp=namei;namei=namek;namek=temp;void print(char*,int);(;)printf(,);运行结果为:10 指向指针的指针指向指针的指针怎样定义一个指向指针数据的指针变量呢?怎样定义一个指向指针数据的指针变量呢?如下:*;的前面有两个*号。*运算符的结合性是从右到左,因此*相当于*(*),显然*是指针变量的定义形式。如果没
49、有最前面的*,那就是定义了一个指向字符数据的指针变量。现在它前面又有一个*号,表示指针变量是指向一个字符指针变量的。*就是所指向的另一个指针变量。例例107 使用指向指针的指针使用指向指针的指针#include void main()char*name=Follow me,BASIC,Great Wall,FORTRAN,Computer design;char*;int;for(;);printf(,*);运行结果为:P 是指向指针的指针变量,第次执行循环体时,p=name+I;使p指向name数组的号元素namep是name的值,即第一个字符串的起始地址用printf函数输出第一个字符串(
50、格式符为s)例例10.28 一个指针数组的元素指向整型数据的简单例子一个指针数组的元素指向整型数据的简单例子#include void main()int,;int*num5=&a0,&a1,&a2,&a3,&a4;int *,;for(;)printf(,*);结果:10.10.有关指针的数据类型和指针运算的小结有关指针的数据类型和指针运算的小结10.8.1有关指针的数据类型的小结有关指针的数据类型的小结定定义义含含义义 ;定定义义整型整型变变量量*;为为指向整型数据的指指向整型数据的指针变针变量量intint a an n;定定义义整型数整型数组组,它有个元素,它有个元素 *;定定义义指指