1、第第6章章 指针指针n6.1 6.1 指针定义与使用指针定义与使用n6.2 6.2 指针与函数指针与函数n6.3 6.3 指针与数组指针与数组n6.4 6.4 指针与字符串指针与字符串n6.5 6.5 指针数组与多级指针指针数组与多级指针n6.6 6.6 指针与动态内存分配指针与动态内存分配n6.7 6.7 指针的深层应用指针的深层应用 1ppt课件6.1 指针的引出指针的引出一一.地址与指针地址与指针 1.地址与取地址运算地址与取地址运算 C程序中的变量在内存中占有一个可标识的存储区程序中的变量在内存中占有一个可标识的存储区,每一个存储区是由若干个字节组成每一个存储区是由若干个字节组成,每一
2、个字节都有每一个字节都有 自己的地址自己的地址,而一个存储区的而一个存储区的 地址是指该存储区中地址是指该存储区中 第一个字节的地址第一个字节的地址C语言允许在程序中使用变量的地址语言允许在程序中使用变量的地址(通过地址运算符通过地址运算符&可得到可得到)如如:float x;变量变量 x 的地址的地址-&x int a10;数组变量数组变量 a 的地址的地址-数组名数组名 a 2ppt课件2.指针与指针变量指针与指针变量(1)变量的访问方式变量的访问方式 直接访问直接访问:通过变量名或地址访问变量的存储区通过变量名或地址访问变量的存储区 例例:scanf(“%d”,&x);x=sqrt(x)
3、;printf(“%d”,x);间接访问间接访问:将一个变量的地址存放在另一个变量中将一个变量的地址存放在另一个变量中.如将变量如将变量 x 的地址存放在的地址存放在 变量变量p 中中,访问访问x 时先找到时先找到p,再由再由p 中存放的地址找到中存放的地址找到 xpx 2012 10101010(2)指针指针:一个变量的指针就是该变量的地址一个变量的指针就是该变量的地址(指针就是地址指针就是地址)(3)指针变量指针变量:存放变量地址的变量存放变量地址的变量,它用来指向另一个变量它用来指向另一个变量3ppt课件 二、二、指针变量的定义指针变量的定义1.格式格式:数据类型数据类型 *指针变量名指
4、针变量名;例例 int *p1;char *p2;2.说明说明:(1)在变量定义时在变量定义时,*号表示该变量是指针变量号表示该变量是指针变量 (注意注意:指针变量是指针变量是p1,p2,不是不是*p1,*p2)(2)定义指针变量后定义指针变量后,系统为其分配存储空间系统为其分配存储空间,用以存放用以存放 其他变量的地址其他变量的地址,但在对指针变量赋值前但在对指针变量赋值前,它并没有它并没有 确定的值确定的值,也不指向一个确定的变量也不指向一个确定的变量例例:int x,*p;x=5;px 2012 101051234注注:指针变量指针变量p的值是随机值的值是随机值,此时此时p 和和 x 并
5、无关联并无关联4ppt课件(3)使指针变量指向一个确定的变量必须进行赋值使指针变量指向一个确定的变量必须进行赋值 int x,*p;x=5;p=&x;px 2012 101051010三、三、指针变量的引用指针变量的引用 1.指针运算符指针运算符*(1)p与与*p不同不同,p是指针变量是指针变量,p的值是的值是p所指向的变量的地址所指向的变量的地址 *p 是是p 所指向的变量所指向的变量,*p的值是的值是p所指向的变量的值所指向的变量的值*p 的值为的值为 5(*p 表示表示 x),而而p 的值为的值为 1010(2)引用指针变量时的引用指针变量时的*与与 定义指针变量时的定义指针变量时的*不
6、同不同 定义变量时的定义变量时的*只是表示其后的变量是指针变量只是表示其后的变量是指针变量 5ppt课件int a,*p;p=&a;scanf(“%d”,p);printf(“%dn”,*p);*p=12;printf(“%dn”,*p);pa 2012 10105101012让让p指向指向a 对对a 重新赋值重新赋值等价于等价于 a=12 即即&a2.&与与*p=&a;*&a *(&a)*p a&*p&(*p)&a6ppt课件2abcd5 3.*与与+,-int a=2,b=5,c,d,*p;p 的值为的值为a 的地址的地址,*p 的值为的值为2p 的值不变的值不变,*p 的值为的值为 3(
7、2)c=*p+;c=*(p+);c=*p;p+;执行后执行后 c 的值为的值为 3 ,*p 的值为的值为 5(3)d=*+p;d=*(+p);+p;d=*p;执行后执行后 d 的值为的值为 3,*p 的值为的值为 3p 2012 10101010(1)p=&a;(*p)+;(等价于等价于 a+;)101233101437ppt课件例例6.2#include void 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(“a=%d,b=%d n”,a,b);printf(“ma
8、x=%d,min=%d n”,*p1,*p2);abp1p2p&a&b&a&b&a59输出结果输出结果:a=5,b=9max=9,min=58ppt课件一、一、指针变量作函数参数指针变量作函数参数例例:2个数按大小顺序输出个数按大小顺序输出#include void swap(int x,int y)int temp;temp=x;x=y;y=temp;void main()int a,b;scanf(“%d%d”,&a,&b);if (ab)swap(a,b);printf(“a=%d,b=%dn”,a,b);abxytemp5说明说明:该程序不能实现该程序不能实现a 和和b 的交换因为实参
9、的交换因为实参a,b 对形参对形参x,y 是是“值传递值传递”,x 和和y 的的变变化不影响化不影响a 和和b 所以输出为所以输出为:a=5,b=99mainswap559956.2 指针与函数指针与函数9ppt课件例例 6.3#include void swap1(int *p1,int *p2)int temp;temp=*p1;*p1=*p2;*p2=temp;void main()int a,b,*pt1,*pt2;scanf(“%d%d”,&a,&b);pt1=&a;pt2=&b;if(ab)swap1(pt1,pt2);printf(“a=%d,b=%dn”,a,b);abp1p2
10、temp&b&apt1pt25说明说明:这种方法是交换这种方法是交换p1和和p2所指向的变量的值所指向的变量的值,即即交换交换main函数中函数中a 和和b的值的值所以输出为所以输出为:a=9,b=5mainswap159&a&b9510ppt课件例例 6.3#include void swap2(int *p1,int *p2)int *temp;*temp=*p1;*p1=*p2;*p2=*temp;说明说明:这种方法可能会破坏系统的正常这种方法可能会破坏系统的正常工作状态,因为工作状态,因为temp是一个指针变量是一个指针变量但是但是在函数中并没有给在函数中并没有给temp一个确定一个确
11、定的地址,这样它所指向的内存单元是的地址,这样它所指向的内存单元是不可预见的不可预见的,而对,而对*temp的赋值可能的赋值可能带来危害带来危害abpt1pt2main&a&bp1p2temp&b&aswap2?随机值随机值5595911ppt课件例例 6.3#include void swap3(int *p1,int *p2)int *p;p=p1;p1=p2;p2=p;p1p2p&a&a&b这种方法是交换形参这种方法是交换形参p1和和p2的值的值,使它们的指向发生改变使它们的指向发生改变,但是但是main函数中的函数中的a和和b的值并没有进行交换的值并没有进行交换所以输出为所以输出为:a
12、=5,b=95a9b&apt1&bpt2main&b&aswap312ppt课件 前面我们用到的函数前面我们用到的函数,有些无返回值有些无返回值,有些有返回值有些有返回值,返回值返回值 类型多为类型多为 int,float,char.一个函数的返回值也一个函数的返回值也可以是一个指针可以是一个指针 类型的数据类型的数据(即地址即地址)定义函数定义函数:数据类型数据类型 *函数名函数名(形参表列形参表列)函数体函数体;例例:int *fun(int a,int b)函数体函数体;说明说明:定义一个返回指针值的函数与以前定义函数格式定义一个返回指针值的函数与以前定义函数格式基本类似基本类似,只是只
13、是在函数名前加在函数名前加*,它表明该函数返回一个它表明该函数返回一个指针值指针值,而这个指针值是指向一个而这个指针值是指向一个 int 型数据型数据二、函数返回二、函数返回 指针指针13ppt课件例例:#include#include#define SIZE 100char bufSIZE;char *p=buf;char *alloc(int n)char *begin;if(p+n=buf+SIZE)begin=p;p=p+n;return(begin);else return(NULL);void main()char*p1,*p2;int i;p1=alloc(10);strcpy(
14、p1,”123456789”);p2=alloc(5);strcpy(p2,”abcd”);printf(“buf=%pn”,buf);printf(“p1=%pn”,p1);printf(“p2=%pn”,p2);puts(p1);puts(p2);for(i=0;i15;i+)printf(“%c”,bufi);14ppt课件buf0buf1 :buf9buf10 :buf14buf15 :buf99bufp buf+10p1 p2 mainbeginn allocbufbufbuf+1012:90a:010buf+15beginn allocbuf+10515ppt课件函数的指针函数的指
15、针:函数的入口地址函数的入口地址 在程序执行过程中调用函数时在程序执行过程中调用函数时,计算机会转去执行计算机会转去执行函数体内的语句函数体内的语句,因此计算机必须知道函数在什么地方。因此计算机必须知道函数在什么地方。实际上函数在内存中也要占据一片存储单元实际上函数在内存中也要占据一片存储单元,这片存储这片存储单元一个起始地址单元一个起始地址,我们称其为我们称其为函数的入口地址函数的入口地址,即函数的指针即函数的指针,这个函数的入口地址是用这个函数的入口地址是用函数名函数名来表示。来表示。因此我们可以定义一个指针变量因此我们可以定义一个指针变量,让它的值等于让它的值等于函数的入口地址函数的入口
16、地址,然后可以通过这个指针变量来调用然后可以通过这个指针变量来调用函数函数,该指针变量称为指向函数的指针变量该指针变量称为指向函数的指针变量 三、指向函数的三、指向函数的 指针指针16ppt课件指向函数的指针变量指向函数的指针变量 1.定义格式定义格式:数据类型数据类型 (*指针变量名指针变量名)(形参表列形参表列);int (*pt)(int arr ,int n);说明说明:数据类型数据类型:指针变量所指向的函数的返回值类型指针变量所指向的函数的返回值类型 形参表列形参表列:即指针变量所指向的函数的形参表列即指针变量所指向的函数的形参表列 格式中的小括号不能省略格式中的小括号不能省略 2.
17、应用应用(1)让指针变量指向函数让指针变量指向函数 pt=add;因为函数名为函数的入口地址因为函数名为函数的入口地址,所以直接将函数名所以直接将函数名 赋给指针变量即可赋给指针变量即可 (2)使用指针变量调用函数使用指针变量调用函数 格式格式:(*指针变量名指针变量名)(实参表列实参表列)17ppt课件例例 求一维数组中全部元素的和求一维数组中全部元素的和#include int add(int b ,int n);void main()int a6=1,3,5,7,9,11,total;int (*pt)(int b ,int n);pt=add;total=(*pt)(a,6);prin
18、tf(“total=%d n”,total);int add(int b ,int n)int i,sum=0;for(i=0;in;i+)sum=sum+bi;return(sum);定义指向函数定义指向函数的指针变量的指针变量令指针变量令指针变量pt 指向函数指向函数add通过通过pt 调用调用函数函数add18ppt课件6.3 指针与数组指针与数组 一一.一维数组与指针一维数组与指针 1.一维数组及元素的地址表示一维数组及元素的地址表示 int a5=1,2,3,4,5 ;数组的地址数组的地址:a 元素元素 地址地址 *a a0&a0 a *(a+1)a1&a1 a+1*(a+2)a2&
19、a2 a+2*(a+3)a3&a3 a+3*(a+4)a4&a4 a+419ppt课件2.用指针变量引用数组元素用指针变量引用数组元素(1)定义指针变量定义指针变量 int *p,a5=1,2,3,4,5 ;p=a;(2)引用数组元素引用数组元素 下标法下标法 地址法地址法 指针法指针法第第k个元素个元素 ak*(a+k)*(p+k)第第k个元素的地址个元素的地址&ak a+k p+k 注意注意:指针变量也可以加下标指针变量也可以加下标 pk 等价于等价于 ak 分别用三种方法输出数组元素分别用三种方法输出数组元素,其效率不同其效率不同,下标法与地址法的效率相同下标法与地址法的效率相同,指针法
20、的效率较快指针法的效率较快 用指针变量访问数组元素时要注意下标是否越界用指针变量访问数组元素时要注意下标是否越界 20ppt课件 例例:将数组将数组a中全部元素加中全部元素加1,再输出再输出a#include void main()int a5=1,3,5,7,9,*p,j;for(p=a;pa+5;p+)printf(“%3d”,*p);printf(“n”);for(j=0;j5;j+)aj=aj+1;for(j=0;j5;j+)printf(“%3d”,*(p+j);printf(“n”);p=a;1 3 5 7 9aa+1a+2a+3a+4246810p可以用可以用p+,但不能用但不能
21、用a+因为因为a 代表数组的起始地址代表数组的起始地址 它是地址常量它是地址常量,不能改变不能改变 而而p 是一个指针变量是一个指针变量使用指针变量时要注意它的当前值使用指针变量时要注意它的当前值21ppt课件3.指向数组的指针变量作函数参数指向数组的指针变量作函数参数例例6.7 实参和形参都用数组名实参和形参都用数组名#include void inv1(int x ,int n)int temp,i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;void main()int i,a6=1,3,4,6,7,9;inv1(a,
22、6);for(i=0;i6;i+)printf(“%3d”,ai);printf(“n”);a0a1a2a3a4a5x0 x1x2x3x4x5134679976431maininv122ppt课件例例6.7 实参用数组名实参用数组名,形参用指针变量形参用指针变量#include void inv2(int *x,int n)int temp,m=(n-1)/2;int *p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;void main()int i,a6=1,3,4,6,7,9;inv2(a,6);for(i=0;
23、i6;i+)printf(“%3d”,ai);printf(“n”);134679a0a1a2a3a4a5axai6na+5ja+2pinv29173642mtemp1a+1a+4a+2a+33 4i和和j的指向会变化的指向会变化,p的指向保持不变的指向保持不变23ppt课件例例6.7 实参和形参都用指针变量实参和形参都用指针变量#include void inv3(int *x,int n);void main()int *p,a6=1,3,4,6,7,9;p=a;inv3(p,6);for(p=a;pa+6;p+)printf(“%3d”,*p);printf(“n”);void inv3
24、(int *x,int n)int temp,m=(n-1)/2;int *p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;例例6.7 实参用指针变量实参用指针变量,形参用数组名形参用数组名#include void inv4(int x ,int n);void main()int *p,a6=1,3,4,6,7,9;p=a;inv4(p,6);for(p=a;pa+6;p+)printf(“%3d”,*p);printf(“n”);void inv4(int x ,int n)int temp,i,j,m=(n-
25、1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;24ppt课件例例6.8 求数组中最大和最小元素求数组中最大和最小元素#include int max,min;void m1(int arr ,int n)int *p,*end;end=arr+n;max=min=*arr;for(p=arr+1;pmax)max=*p;else if(*pmin)min=*p;void main()int i,a6;for(i=0;i6;i+)scanf(“%d”,&ai);m1(a,6);printf(“max=%d,min=%dn”,max,min);
26、a0a1a2a3a4a56narr+1parr+6endmaxmin471905aarr447 91 025ppt课件二、二维数组与指针二、二维数组与指针二维数组的定义二维数组的定义a0a1a2a00a01a02a03a10a11a12a13a20a21a22a23对于二维数组对于二维数组a,首先可以把它先理解为一个,首先可以把它先理解为一个一维数组一维数组,它有它有3个个元素元素:a0,a1,a2而每一个元素又是一个一维数组而每一个元素又是一个一维数组,包含包含4个元素个元素如如a0是一维数组是一维数组,它有它有4个元素个元素:a00,a01,a02,a03a34 a0,a1,a2只是一种地
27、址表示方法只是一种地址表示方法,并不真的二维数组元素,并不真的二维数组元素,可以看作是可以看作是第二重第二重一维数组的名字。一维数组的名字。26ppt课件二维数组的初始化二维数组的初始化(1)可以分行给二维数组赋初值可以分行给二维数组赋初值int a34=1,2,3,4,5,6,7,8,9,10,11,12;1 2 3 45 6 7 8910 11 12(2)可以将所有数据写在一个花括号中,按可以将所有数据写在一个花括号中,按顺序对各元素赋初值顺序对各元素赋初值int a34=1,2,3,4,5,6,7,8,9,10,11,12;27ppt课件二维数组的初始化二维数组的初始化(3)可以对部分元
28、素赋初值,其余元素可以对部分元素赋初值,其余元素补补0int a34=1,5,9;159int a34=1,0,6,0,0,11;10 60 0 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 028ppt课件(4)如果对全部数据都赋初值,则定义时第一维的如果对全部数据都赋初值,则定义时第一维的长度可以不指定,但第二维的长度不能省长度可以不指定,但第二维的长度不能省int a 4=1,2,3,4,5,6,7,8,9,10,11,12;二维数组的初始化二维数组的初始化 如果只对部分数据赋初值,第一维的长度也可如果只对部分数据赋初值,第一维的长度也可以不指定,但元素必须分行赋初值以不
29、指定,但元素必须分行赋初值int a 4=0,0,3,0,10;0 0 3 00 0 0 0010 0 029ppt课件二维数组的地址二维数组的地址 a0 a1 a2l二维数组名二维数组名a表示二维数组的首地址表示二维数组的首地址,也是第也是第0个元素个元素(a0)的地址的地址a,&a0a+1,&a1a+2,&a2a+1代表第代表第1个元素个元素(a1)的地址的地址 a+1&a1a+2代表第代表第2个元素个元素(a2)的地址的地址 a+2&a2a&a030ppt课件a00 a01 a02 a03a10 a11 a12 a13a20 a21 a22 a23a,&a0a+1,&a1a+2,&a2l
30、a0,a1,a2既然是第二重一维数组名既然是第二重一维数组名,它们就代表了它们就代表了相应一维数组的首地址相应一维数组的首地址,因此因此a0代表了第代表了第0行第行第0列元素列元素的地址的地址,即即二维数组的地址二维数组的地址a1&a10 a1+2&a12a2&a20a2+3&a23a0&a00a0+1&a01a2&a20 a2+3&a23a1+2&a12a1&a10 a0&a00 a0+1&a01 31ppt课件Question*a,*a+1,*(a+1),*(a+2)+3分别表示什么值?分别表示什么值?a23a22a21a20a13a12a11a10a03a02a01a0032ppt课件二
31、维数组的地址二维数组的地址a00 a01 a02 a03a10 a11 a12 a13a20 a21 a22 a23a,&a0a+1,&a1a+2,&a2*(a+2)+3a2+3&a23因因a&a0 所以所以*a *(&a0)a0&a00即即*a表示元素表示元素a00的地址的地址a0&a00*a*a+1表示元素表示元素a01的地址的地址*(a+1)表示元素表示元素a10的地址的地址*(a+2)+3表示元素表示元素a23的地址的地址*(a+1)a1&a10*a+1a0+1&a0133ppt课件二维数组的地址二维数组的地址小结:小结:l二维数组名二维数组名a代表二维数组的首地址代表二维数组的首地址
32、,即即:第第0行的地址为行的地址为 a&a0第第1行的地址为行的地址为 a+1&a1第第2行的地址为行的地址为 a+2&a2l二维数组元素的地址二维数组元素的地址a23a12a10a01a00元素元素&a23&a12&a10&a01&a00地址地址a2+3a1+2a1a0+1a0地址地址*(a2+3)*(a1+2)*a1*(a0+1)*a0元素元素*(a+2)+3*(a+1)+2*(a+1)*a+1*a地址地址*(*(a+2)+3)*(*(a+1)+2)*(*(a+1)*(*a+1)*a元素元素34ppt课件指向二维数组元素的指针指向二维数组元素的指针例例1:用指针变量输出二维数组中的元素:用
33、指针变量输出二维数组中的元素Quizp=a;p=&a00;p=*a;p=*a0;#includevoid main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int *p;for(p=a0;pa0+12;p+)printf(“%d ”,*p);printf(“n”);35ppt课件2026q指向二维数组元素的指针指向二维数组元素的指针int a34;int *p;p=a;合法吗?合法吗?int x=36,*q,*p;q=&x;p=&q;362010 x2048p20102026a0a1a2p是二级指针是二级指针,它指向一个整型指针变量它指向一个整型指针变量q,而而
34、q指向一个整型变量指向一个整型变量 a是一种地址表示方法是一种地址表示方法,a实际指向了第一重一实际指向了第一重一维数组元素维数组元素a0,而,而 a0是第二重一维数组是第二重一维数组aa00 a01 a02 a03非法!非法!36ppt课件指向二维数组元素的指针指向二维数组元素的指针 定义格式:类型名定义格式:类型名(*指针变量名)指针变量名)数组长度数组长度;int a34;int (*p)4;p=a;p指向一个包含有指向一个包含有4个个整型数据的一维数组整型数据的一维数组合法!合法!虽然在定义虽然在定义p的时候只用了一个的时候只用了一个*,但,但p实际上是一个二级指针变量实际上是一个二级
35、指针变量37ppt课件指向二维数组元素的指针指向二维数组元素的指针例例2:输出二维数组中的元素:输出二维数组中的元素#includevoid main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int (*p)4,i,j;p=a;for(i=0;i3;i+)for(j=0;j4;j+)printf(“%6 6d”,*(*(p+i)+j);printf(“n”);38ppt课件指向二维数组元素的指针指向二维数组元素的指针二维数组用得较多的是二维数组用得较多的是“字符串数组字符串数组”,配合字,配合字符串的操作,使字符串处理更加方便、灵活。符串的操作,使字符串处理更加
36、方便、灵活。char a4256=Pascal,VC,Basic,Java;a0a1a2a3P a s c a lV cB a s i cJ a v a000039ppt课件#include#include#define MAXLEN 256#define N 4void main()int i,j;char tempMAXLEN;char nameNMAXLEN=Pascal,VC,Basic,Java;for(i=0;iN;i+)puts(namei);/书的数量书的数量for(i=0;iN-1;i+)for(j=i+1;j0)strcpy(temp,namei);strcpy(namei
37、,namej);strcpy(namej,temp);选择法排序选择法排序/书名的最大长度书名的最大长度+1+1指向二维数组元素的指针指向二维数组元素的指针比较两个字符比较两个字符串大小串大小 复制字符串复制字符串 Quiz选择法排序选择法排序40ppt课件Assignment1、将数组、将数组a23中的每个元素向右移一列中的每个元素向右移一列,最后一列最后一列换到最左一列(如右图所示)换到最左一列(如右图所示)要求:必须用要求:必须用指针指针实现实现321654=a2135462、将数组、将数组aMN中的每个元素中的每个元素向右移一列向右移一列,最后一列换到最左最后一列换到最左一列一列要求:
38、必须用要求:必须用指针指针实现实现41ppt课件Experiment实验题目:实验题目:指向二维数组的指针编程指向二维数组的指针编程 实验目的:实验目的:深入理解如何用指针变量表示二维数组的深入理解如何用指针变量表示二维数组的 元素和元素的地址,学会用指向二维数组元素和元素的地址,学会用指向二维数组 的指针变量作函数参数的指针变量作函数参数实验内容:实验内容:编程找出二维数组中的编程找出二维数组中的鞍点鞍点,二维数组的,二维数组的 鞍点是指在该位置上的元素在该行上最大,鞍点是指在该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。在该列上最小,也可能没有鞍点。要求必要求必 须用指针实现。
39、须用指针实现。编写一个找鞍点的函数,用指向二维数组编写一个找鞍点的函数,用指向二维数组 的指针变量作函数参数的指针变量作函数参数42ppt课件6.4 指针与字符串指针与字符串一、字符指针一、字符指针 1.定义指向字符串的指针变量定义指向字符串的指针变量 char *p=“China”;说明说明:这里没有定义字符数组这里没有定义字符数组,但字符串在内存中还是以数组但字符串在内存中还是以数组形式存放的形式存放的.字符串在内存中字符串在内存中占有一片连续的存储单元占有一片连续的存储单元,以以0结束结束 注意注意:赋值只是把字符串的首地址赋给赋值只是把字符串的首地址赋给p,而不是把字符串赋给而不是把字
40、符串赋给 p,p 是一个指针变量是一个指针变量,它不能存放一个字符串它不能存放一个字符串,只能存放一个地址只能存放一个地址China02460246124622463246424652460p 将字符串的将字符串的首地址赋给首地址赋给p43ppt课件2.输出字符串输出字符串:printf(“%sn”,p);输出字符串时输出字符串时,先输出先输出p 指向的指向的第一个字符第一个字符,然后系统自动执行然后系统自动执行p+,使使p 指向下一个字符指向下一个字符,再输出该字符再输出该字符,直到遇到直到遇到0 为止为止也可以用循环逐个输出字符串中的字符也可以用循环逐个输出字符串中的字符:for(;*p!
41、=0;p+)printf(“%c”,*p);China02460246124622463246424652460p24612462246324642465二、二、字符数组与字符指针变量的区别字符数组与字符指针变量的区别 char s =“C Language”;char *p=“C Language”;1.存储方式不同存储方式不同:s 存放的是字符串中的存放的是字符串中的字符和字符和0 p 存放的是字符串的存放的是字符串的首地址首地址44ppt课件2.虽然虽然s 和和p 都能代表字符串的首地址都能代表字符串的首地址,但但s是数组名是数组名,是一个常量是一个常量,而而p是一个指针变量是一个指针变
42、量,因此因此 s+的的 写法是错的写法是错的,而而p+的写法是对的的写法是对的char *p1,*p2=“abcd”;p1=“China”;char s12,str =“good”;s12=“China”;s=“China”;3.赋值方式不同赋值方式不同 s 可以进行初始化可以进行初始化,但不能使用赋值语句但不能使用赋值语句 p 既可以初始化既可以初始化,也可以赋值也可以赋值错错4.定义数组定义数组s 时时,系统会给系统会给s 分配一片连续的存储单元分配一片连续的存储单元 定义指针变量定义指针变量p 时时,只给只给p 分配一个存储单元分配一个存储单元45ppt课件三、字符串指针作函数参数三、字
43、符串指针作函数参数例例6.20 实现字符串复制实现字符串复制 void copystr(char from ,char to)int i=0;while(fromi!=0)toi=fromi;i+;toi=0;void mani()char a =“cat”,b =“tiger”;puts(a);puts(b);copystr(a,b);puts(a);puts(b);cat0tiger0abfromatobcat0相当于相当于bi=ai46ppt课件例例 6.20 void copystr(char*from,char *to)for(;*from!=0;from+,to+)*to=*from;*to=0;void main()char *a=“cat”,*b=“tiger”;puts(a);puts(b);copystr(a,b);puts(a);puts(b);cat0tiger0abfromatobcat0a+1b+1a+2b+2a+3b+347ppt课件