《《C语言综合实验》1数组与指针.ppt》由会员分享,可在线阅读,更多相关《《C语言综合实验》1数组与指针.ppt(65页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1C C语言综合实验语言综合实验谢颂华谢颂华2C C语言综合实验语言综合实验指针与数组指针与数组构造数据类型构造数据类型链表链表3指针与数组指针与数组基本概念基本概念变量的指针和指针变量变量的指针和指针变量指针和数组指针和数组指针和字符串指针和字符串指针函数和函数的指针指针函数和函数的指针指针数组指针数组例题讲解例题讲解4主要内容主要内容指针的引用和运算方法指针的引用和运算方法数组、函数和字符串与指针的关系数组、函数和字符串与指针的关系学习难点学习难点指针变量的引用指针变量的引用指针作为函数参数的运用指针作为函数参数的运用5基本概念基本概念内存:内存:内部存储器,是由存储单元组成的。内部存储器
2、,是由存储单元组成的。特点特点:存储单元是线性连续。存储单元是线性连续。存储单元的最小单位是字节。存储单元的最小单位是字节。1.1.内存的概念内存的概念6地地址址:为为了了访访问问内内存存中中的的某某个个存存储储单单元元,我我们们要要为为它它编编号,这种编号称为号,这种编号称为内存地址内存地址。通通过过地地址址就就能能够够访访问问该该地地址址所标识的存储单元。所标识的存储单元。内内存存单单元元的的地地址址和和内内存存单单元元的内容的区别:的内容的区别:2.2.地址的概念地址的概念int i,j,k;int i,j,k;i=3,j=5;i=3,j=5;低地址低地址高地址高地址2000200020
3、0220022004200430003000i ij jk k00000011000000110000000000000000000001010000010100000000000000007变变量量的的地地址址:变变量量在在内内存存中中占占用用几几个个连连续续的的 字节,开始字节的地址,就是变量的地址。字节,开始字节的地址,就是变量的地址。2007变量的指针:变量的指针:一个变量的地址称为该变量的指针一个变量的地址称为该变量的指针,指针是内存地址的别名指针是内存地址的别名。指针变量:指针变量:若一个变量专用于存放另一个变量的地若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量
4、(特殊性,指址(指针),则该变量称为指针变量(特殊性,指针变量的存储单元存放的不是针变量的存储单元存放的不是普通数据普通数据,而是而是地址地址)注意区分注意区分“指针指针”和和“指针变量指针变量”这两个概这两个概念。念。指针的对象:指针的对象:当把变量的地址存入指针变量后,当把变量的地址存入指针变量后,我们就可以说我们就可以说这个指针指向了该变量这个指针指向了该变量。变量的存取方法:变量的存取方法:直接存取和间接存取直接存取和间接存取 直接存取:直接存取:直接根据变量名存取数据直接根据变量名存取数据 间接存取:间接存取:通过指针变量存取相应变量的数据通过指针变量存取相应变量的数据 10 数据所
5、占有的内存单元个数是由其数据类型数据所占有的内存单元个数是由其数据类型决定的;决定的;首地址:即第一个内存单元的地址;首地址:即第一个内存单元的地址;表示地址的数与整数的区别;表示地址的数与整数的区别;变量变量i、j的地址可能相邻,也可能不相邻,是的地址可能相邻,也可能不相邻,是由系统分配的,我们不必关心。由系统分配的,我们不必关心。3.3.说明说明 程序中定义的每个变量在编译后都占有各自程序中定义的每个变量在编译后都占有各自的内存单元,系统是通过内存地址对变量进的内存单元,系统是通过内存地址对变量进行存取的;行存取的;变量的指针和指向变量的指针变量变量的指针和指向变量的指针变量一、指针变量的
6、定义一、指针变量的定义 一般形式:一般形式:类型标识符类型标识符 *变量名;变量名;例如例如:int*ptr1,*ptr2;指针变量的类型:指针变量的类型:指明了该指针指向的内存空指明了该指针指向的内存空 间所存储的间所存储的数据的类型数据的类型 在定义指针变量时要注意以下几个问题在定义指针变量时要注意以下几个问题:变量名变量名ptr2前面的前面的*”不能省略,如果写成不能省略,如果写成 int*ptr1,ptr2;则则ptr2被定义为整型变量,而非整型指针变量。被定义为整型变量,而非整型指针变量。12定义中的定义中的*”表示所定义的变量是指针变量,但表示所定义的变量是指针变量,但 指针变量名
7、是指针变量名是ptr1、ptr2,而非,而非*ptr1、*ptr2。指针变量只能指向定义时所规定类型的变量。指针变量只能指向定义时所规定类型的变量。这个规定的类型称为该指针变量的这个规定的类型称为该指针变量的基类型基类型”。如:上例中如:上例中ptr1、ptr2只能指向整型变量,不能指向只能指向整型变量,不能指向实型或字符型变量。其实型或字符型变量。其基类型基类型”相同,都是整型。相同,都是整型。定义指针变量后,并未确定该变量指向何处。定义指针变量后,并未确定该变量指向何处。即该变量的值是不确定的。在引用指针变量前即该变量的值是不确定的。在引用指针变量前 必须首先让它指向一个变量,这一点非常重
8、要。必须首先让它指向一个变量,这一点非常重要。13二、指针变量的运算二、指针变量的运算 指针运算符指针运算符(&”和和*”)&”(地址运算符地址运算符):取变量的存储地址取变量的存储地址*”(引用运算符引用运算符):取指针所指向取指针所指向变量变量的内容的内容例如:例如:&i 是求变量是求变量i的地址。的地址。ptr指向了指向了i变量,变量,*ptr表示表示i的值,即的值,即3 还可以用这种方法实现对变量的改变:还可以用这种方法实现对变量的改变:*ptr=15;/等价于等价于 i=15由由此此可可见见:通通过过指指针针运运算算符符*”可可以以引引用用一一个个变变量量。如如:当当ptr已已经经指
9、指向向变变量量i后后,*ptr就等同于就等同于i。进一步理解进一步理解&”和和*”:&”运算和运算和*”运算是一对互逆运算运算是一对互逆运算&*ptr&i ptr *&i *ptr i等价于等价于 指针的赋值运算(指针的赋值运算(=)指针的赋值运算指针的赋值运算:把地址赋值给指针变量。把地址赋值给指针变量。指针的赋值运算可以是以下三种方式指针的赋值运算可以是以下三种方式:使用取地址运算符,把地址值赋值给指针变量。使用取地址运算符,把地址值赋值给指针变量。如:如:int i,*pi;pi=&i;把指针变量的值赋给另一个指针变量。把指针变量的值赋给另一个指针变量。如:如:int i,*pa,*pb
10、;pa=&i;pb=pa;给指针变量赋值为符号常量给指针变量赋值为符号常量NULL。说说明明:NULL是是一一个个空空指指针针,表表示示该该指指针针变变量量的的值值没没有有意意义义。作作用用是是为为了了避避免免对对没没有有被被初初始始化化的的指指针针变变量量的的非非法引用。法引用。NULL 的定义在的定义在stdio.h”中。中。如:如:int*pi;pi=NULL;16说明:说明:(1)在定义指针变量时,可以立即将一个地址值赋给指针在定义指针变量时,可以立即将一个地址值赋给指针变量,这就是变量,这就是指针变量的初始化指针变量的初始化。如:如:float flt,*f_ptr=&flt;(2)
11、指针变量间的赋值和引用应保证基类型相同。指针变量间的赋值和引用应保证基类型相同。若有定义:若有定义:int*p,i;float*q,x;则:则:q=&i;p=&x;(3)可以将数组名或函数名赋给某些类型的指针变量;可以将数组名或函数名赋给某些类型的指针变量;int a10,*ip;ip=&a0;ip=&a0;ip=a;(4)不能将一个整型量不能将一个整型量(或任何其它非地址类型的数据或任何其它非地址类型的数据)赋赋给一个指针变量;给一个指针变量;int *ip;ip=3000;ip=3000;#include void main()int a1=11,a2=22;int *p1,*p2;p1=
12、&a1;p2=&a2;printf(%d,%dn,*p1,*p2);p2=p1;printf(%d,%dn,*p1,*p2);11a122a2不定p1不定p2&a1&a2*p1*p2&a1*p2*p2说明:说明:多个指针可以指向同一个存储单元。但在某一时多个指针可以指向同一个存储单元。但在某一时刻,一个指针变量只能指向一个存储单元,因为指针变刻,一个指针变量只能指向一个存储单元,因为指针变量在某一时刻只能存放一个变量的地址值。量在某一时刻只能存放一个变量的地址值。例:例:多个指针可以指向同一个存储单元多个指针可以指向同一个存储单元#include void main()int a1=11,a2
13、=22;int *p1,*p2,*p;p1=&a1;p2=&a2;printf(%d,%dn,*p1,*p2);p=p1;p1=p2;p2=p;printf(%d,%dn,*p1,*p2);11a122a2不定p1不定p2不定p&a1&a2*p1*p2&a1&a2*p1*p1&a1*p2例:例:使两个指针交换指向使两个指针交换指向Eg802.cpp#include void main()int a1=11,a2=22,t;int *p1,*p2;p1=&a1;p2=&a2;printf(%d,%dn,a1,a2);t=*p1;*p1=*p2;*p2=t;printf(%d,%dn,a1,a2)
14、;11a122a2不定t不定p1不定p2&a1*p1&a2*p2112211例:例:交换两个指针变量所指向变量的值交换两个指针变量所指向变量的值Eg803.cpp 移动指针的运算移动指针的运算 指针的加减运算(指针的加减运算(+、)、)指针的自加自减运算(指针的自加自减运算(+,-,+=,-=)1 1指针的指针的+、运算、运算 指针指针整数整数指针指针指针指针+、说明说明:指针与整型值加减的结果是指针指针与整型值加减的结果是指针,表示使该指针指,表示使该指针指向该指针向该指针下移下移或或上移上移存储单元个数存储单元个数(整型值整型值)之后的内之后的内存地址。存地址。存储单元的大小存储单元的大小
15、就是该指针的数据类型所需就是该指针的数据类型所需的内存大小。的内存大小。例如:例如:ptr+n(指针指针ptr,n为整数为整数)这个指针值代表的内存单这个指针值代表的内存单元的地址是:元的地址是:ptr+n*d(其中其中d是指针所指向变量的数据类型是指针所指向变量的数据类型所占内存字节数所占内存字节数),即指针移动了,即指针移动了n个元素。个元素。指针与指针的加运算毫无意义,所以指针与指针的加运算毫无意义,所以指针与指针指针与指针 没有加运算没有加运算。指针与指针的减运算要求相减的两个指针属于同指针与指针的减运算要求相减的两个指针属于同 一类型,其结果是整数,表示两个指针之间的数一类型,其结果
16、是整数,表示两个指针之间的数 据的个数。其结果值的计算公式是:据的个数。其结果值的计算公式是:ptr1-ptr2=(ptr1的值的值-ptr2的值的值)/指针的数据类型所占字节数指针的数据类型所占字节数 例如:例如:int*ptr1,*ptr2,*ptr3,x;int ary5=2,4,8,16,32;ptr1=&ary0;ptr2=&ary3;ptr3=ary;x=ptr2-ptr1;x 的值是的值是?32指针的指针的+、-、+=、-=运算运算+、+=:移动指针到下一个或下几个存储单元移动指针到下一个或下几个存储单元 -、-=:移动指针到上一个或上几个存储单元移动指针到上一个或上几个存储单元
17、 例如:例如:int*ptr,ary5=2,4,6,8,10;ptr=ary;ptr+=3;ptr-;23三、指针变量作为函数参数三、指针变量作为函数参数 指针可以用作函数参数,这在调用函数希望指针可以用作函数参数,这在调用函数希望改变参数的值时非常有用。改变参数的值时非常有用。例如:编写函数,实现两个数的交换例如:编写函数,实现两个数的交换例:例:输入两个整数输入两个整数a、b,按大小顺序输出。,按大小顺序输出。#include void swap(int x,int y)int temp;temp=x;x=y;y=temp;void main()int a,b;printf(nInput
18、a,b:);scanf(%d%d,&a,&b);if (ab)swap(a,b);printf(max=%d,min=%dn,a,b);注意:注意:注意:注意:语言中的函数调语言中的函数调语言中的函数调语言中的函数调用采用用采用用采用用采用“传值传值传值传值”方式,方式,方式,方式,即单向传递方式。即单向传递方式。即单向传递方式。即单向传递方式。即:即:即:即:主调函数可以将实参主调函数可以将实参主调函数可以将实参主调函数可以将实参的值传递给被调函数的的值传递给被调函数的的值传递给被调函数的的值传递给被调函数的形参,但不能通过改变形参,但不能通过改变形参,但不能通过改变形参,但不能通过改变形参
19、的值而改变实参的形参的值而改变实参的形参的值而改变实参的形参的值而改变实参的值。值。值。值。输入:输入:输入:输入:a=5,b=8a=5,b=8输出:?输出:?输出:?输出:?max=5,min=8#include void swap(int*px,int*py)int temp;temp=*px;*px=*py;*py=temp;void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,&a,&b);p1=&a;p2=&b;if (ab)swap(p1,p2);printf(max=%d,min=%dn,a,b);5a8b&ap1&b
20、p2不定不定px不定不定py&a&b858a5b&ap1&bp2输入:输入:输入:输入:a=5,b=8a=5,b=8输出:?输出:?输出:?输出:?max=8,min=5#include void swap(int*px,int*py)int*temp;*temp=*px;*px=*py;*py=*temp;void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,&a,&b);p1=&a;p2=&b;if (ab)swap(p1,p2);printf(max=%d,min=%dn,a,b);错误:错误:错误:错误:*temptemp是
21、指针变量是指针变量是指针变量是指针变量temptemp所指向的变量,但所指向的变量,但所指向的变量,但所指向的变量,但temptemp中并无确定的地址值,中并无确定的地址值,中并无确定的地址值,中并无确定的地址值,其值不确定;其值不确定;其值不确定;其值不确定;*temptemp所指向所指向所指向所指向的单元也不确定。因此,的单元也不确定。因此,的单元也不确定。因此,的单元也不确定。因此,对对对对*temptemp赋值可能会破坏系赋值可能会破坏系赋值可能会破坏系赋值可能会破坏系统的正常工作状况。统的正常工作状况。统的正常工作状况。统的正常工作状况。修改:修改:修改:修改:应该将应该将应该将应该
22、将*pxpx的值赋给的值赋给的值赋给的值赋给一个整型变量,用整型变一个整型变量,用整型变一个整型变量,用整型变一个整型变量,用整型变量作为临时存储空间实现量作为临时存储空间实现量作为临时存储空间实现量作为临时存储空间实现*pxpx和和和和*pypy的交换。的交换。的交换。的交换。#include void swap(int*px,int*py)int*p;p=px;px=py;py=p;void main()int a,b,*p1,*p2;printf(nInput a,b:);scanf(%d%d,&a,&b);p1=&a;p2=&b;if (ab)swap(p1,p2);printf(ma
23、x=%d,min=%dn,a,b);5a8b&ap1&bp2不定不定px不定不定py&a&b&b&a5a8b&ap1&bp2输入:输入:输入:输入:a=5,b=8a=5,b=8输出:?输出:?输出:?输出:?max=5,min=8通过函数调用得到通过函数调用得到通过函数调用得到通过函数调用得到n n个要改变的值的方法:个要改变的值的方法:个要改变的值的方法:个要改变的值的方法:、在主调函数中设、在主调函数中设n个变量,用个变量,用n个指针变量指向它们;个指针变量指向它们;、将、将n变量的地址作为实参传给所调用的函数的形参;变量的地址作为实参传给所调用的函数的形参;、通过形参指针变量,改变该、通
24、过形参指针变量,改变该n个变量的值;个变量的值;、主调函数就可以使用这些改变值的变量;、主调函数就可以使用这些改变值的变量;例例 编写函数,求一维数组中的最大值和最小值。编写函数,求一维数组中的最大值和最小值。void search(int x,int n),int*pmax,int*pmin int*pmax,int*pmin*pmax=*pmin=x0;for(i=1;in;i+)if(*pmaxxi)*pmin=xi;int a20,max,min;for(i=0;i20;i+)scanf(%d,&ai);search(a,20,&max,&min);29指针和数组指针和数组一、数组的指
25、针和指向数组的指针变量的概念一、数组的指针和指向数组的指针变量的概念 数组的指针数组的指针:数组在内存中的起始地址。数组在内存中的起始地址。数组元素的指针数组元素的指针:数组元素的起始地址。数组元素的起始地址。当指针变量指向数组或数组元素时,它就是当指针变量指向数组或数组元素时,它就是指指向数组的指针变量向数组的指针变量。C规定规定:数组名代表数组的首地址(起始地址),数组名代表数组的首地址(起始地址),即第一个元素的地址。即第一个元素的地址。当指针变量当指针变量p指向数组时,指向数组时,p+1指向数组指向数组 的下一个元素。假设一个整型元素占两的下一个元素。假设一个整型元素占两 个字节,个字
26、节,p+1是使是使p的地址加的地址加2个字节。个字节。如:如:int a10,*p;则:则:p=a;与与 p=&a0;等价等价称指针变量称指针变量p指向数组元素指向数组元素a0 p+i、a+i、&ai 都是都是ai的地址。的地址。30二、数组元素的引用二、数组元素的引用 1.用下标法引用数组元素用下标法引用数组元素如:如:a3=45;b25=200;2.用指针法引用数组元素用指针法引用数组元素 如:如:int a10,*p,i;p=a;则:则:*(p+i)、*(a+i)代表元素代表元素ai *(p+i)也可以写成也可以写成pi *(p+i)、*(a+i)、ai、pi 等价,等价,都代表数组都代
27、表数组a的第的第i+1个元素。个元素。31程序举例:输出程序举例:输出10个元素数组中的全部元素。个元素数组中的全部元素。方法方法2:通过数组名计算数组元素地址,找出元素的值通过数组名计算数组元素地址,找出元素的值 main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,*(a+i);方法方法1:下标法:下标法 main()int a10=54,65,8,2,3,56,8,21,57,98,i;for(printf(n),i=0;i10;i+)printf(%4d,ai);方法方法3:用指针变量
28、指向数组元素:用指针变量指向数组元素 main()int a10=54,65,8,2,3,56,8,21,57,98,*p,i;p=a;for(printf(n),i=0;i10;i+)printf(%4d,*p+);以上三种方法,利用指针变量效率最高!以上三种方法,利用指针变量效率最高!程序举例:输出程序举例:输出10个元素数组中的全部元素。个元素数组中的全部元素。33说明:说明:指针变量是地址变量,指针变量是地址变量,数组名是地址常量数组名是地址常量。即。即指针变量的内容可以在程序运行过程中被改变;而指针变量的内容可以在程序运行过程中被改变;而数组名一旦被定义,它的值就不能被改变了。数组名
29、一旦被定义,它的值就不能被改变了。例如:例如:int i,*p,a6;则:则:p=&i;a=&i;a+;a+=i;不能给常量赋值不能给常量赋值指针变量与数组名的区别:指针变量与数组名的区别:利用指针变量编程时特别要注意指针变量的当利用指针变量编程时特别要注意指针变量的当前值。前值。例如:通过指针变量输入输出例如:通过指针变量输入输出a数组元素。数组元素。main()int*p,i,a10;p=a;for(i=0;i10;i+)scanf(%d,p+);for(printf(n”),i=0;i10;i+)printf(%6d”,*p+);应插入语句应插入语句 p=a;注意:注意:*p+、*(p+
30、)、(*p)+、*(+p)的含义的含义 35#include void main()int*p,ary5=2,4,6,8,10;p=ary;p+=3;p-;/*p为为6printf(%4d n,*p+);/printf(%4d n,*(p+);/printf(%4d n,(*p)+);/printf(%4d n,*(+p);例如:指针变量的不同表示形式例如:指针变量的不同表示形式输出结果是?输出结果是?/6/6/6/836*ptr+和和*(ptr+)是一是一样的么的么?*与与+的的优先先级一一样在在*和和+同同时出出现的情况下依据的情况下依据从右到左从右到左的原的原则ptr+先先取值再取值再加
31、一加一.所以所以*ptr+的意思的意思是先取是先取ptr的指的指针值,然后指然后指针值后移指向后移指向下个元素下个元素*ptr+的的结果果还是是*ptr,只有到下个循只有到下个循环时时*ptr的的值才是后个元素才是后个元素三、数组名作函数的参数三、数组名作函数的参数 例如:例如:f(int arr,int n)main()int array10;f(array,10);解释解释:实际上,能够接受并存实际上,能够接受并存放地址值的只能是指针变量。放地址值的只能是指针变量。因此,因此,C编译系统都是将形参编译系统都是将形参数组名作为指针变量来处理数组名作为指针变量来处理的。上例中的。上例中f(in
32、t arr,int n)等价于等价于 f(int*arr,int n)。使用形参数组的概念只使用形参数组的概念只是为了与实参数组对应,直是为了与实参数组对应,直观,便于理解而已。观,便于理解而已。归纳起来,实参与形参的对应关系有:归纳起来,实参与形参的对应关系有:、形参和实参都用数组名:、形参和实参都用数组名:f(int x int x,int n);f(a a,10);把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;把实参数组首地址传给形参作为形参数组首地址;、实参用数组名,形参用指针变量:、实参用数组名,形
33、参用指针变量:f(int*xint*x,int n);f(a a,10);把实参数组首地址传给形参把实参数组首地址传给形参把实参数组首地址传给形参把实参数组首地址传给形参(指针变量指针变量指针变量指针变量),函数中用指,函数中用指,函数中用指,函数中用指针访问实参数组针访问实参数组针访问实参数组针访问实参数组、形参和实参都用指针变量:、形参和实参都用指针变量:f(int*xint*x,int n);f(p p,10);函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值函数调用前应先给实参指针变量赋值(如:如:如:如:int*int*p=ap=a)、
34、实参为指针变量,形参为数组名:、实参为指针变量,形参为数组名:f(int x int x,int n);f(p p,10);实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;实参通过指针变量为形参提供数组首地址;34/55int a10;int a10;39例:从例:从10个数中找出其中最大值和最小值。个数中找出其中最大值和最小值。#include void max_min(int a,int n,int*max,int*min);main()int i,a=2,4,1,6,7,32,45,75,45,90,max,min;for
35、(printf(The original array=),i=0;i10;i+)printf(%5d,ai);max_min(a,10,&max,&min);printf(nmax=%d min=%d,max,min);void max_min(int a,int n,int*max,int*min)int i;*max=*min=a0;for(i=0;in;i+)if(*maxai)*min=ai;40上例中如果形参数组用指针变量,则程序如下:上例中如果形参数组用指针变量,则程序如下:#include void max_min(int*x,int n,int*max,int*min);mai
36、n()int i,a=2,4,1,6,7,32,45,75,45,90,max,min;for(printf(The original array=),i=0;i10;i+)printf(%5d,ai);max_min(a,10,&max,&min);printf(nmax=%d min=%d,max,min);void max_min(int*x,int n,int*max,int*min)int i;*max=*min=*x;for(i=1;in;i+,x+)if(*max*x)*min=*x;指针和字符串指针和字符串字符串的指针:字符串的指针:字符数组在内存中存放的首地址。字符数组在内存
37、中存放的首地址。指向字符串的指针变量:指向字符串的指针变量:专门用来存放字符数组专门用来存放字符数组首地址的变量。首地址的变量。例如:例如:char*strp=Hello!”;定定义义了了一一个个指指向向字字符符串串的的指指针针变变量量,并并将将字字符符串串的的首首地地址址赋赋值值给给strp指指针针变变量量,即即:使使指指针针变变量量strp指指向向字字符符串首地址。串首地址。字符指针变量定义的一般形式字符指针变量定义的一般形式:char*指针变量名指针变量名;字符指针变量定义时可以赋初值。字符指针变量定义时可以赋初值。C程序访问字符串有以下两种方法程序访问字符串有以下两种方法:1 用字符数
38、组存放一个字符串用字符数组存放一个字符串 例如:例如:char s=I am a student.;字符串输出语句可写成:字符串输出语句可写成:printf(%sn,s);for(i=0;si;i+)printf(%c,si);for(i=0;si;i+)printf(%c,*(s+i);也可用也可用si!=02用字符指针指向一个字符串用字符指针指向一个字符串 例如:例如:char*ps=I am a student.;字符串输出语句可写成:字符串输出语句可写成:printf(%sn,ps);for(;*ps;ps+)printf(%c,*ps);说明:说明:字符数组由若干个元素组成,每个元素
39、中放一个字符。字符数组由若干个元素组成,每个元素中放一个字符。而字符指针变量中存放的是地址(字符串的首地址),而字符指针变量中存放的是地址(字符串的首地址),决不是将字符串放到字符指针变量中;决不是将字符串放到字符指针变量中;字符数组和字符指针变量都可以在定义时赋初值,但以字符数组和字符指针变量都可以在定义时赋初值,但以下方法对字符数组非法,对字符指针变量合法:下方法对字符数组非法,对字符指针变量合法:char s10;s=hello!;char*ps;ps=hello!;字符指针变量必须先赋值后使用,否则对系统构成危险。字符指针变量必须先赋值后使用,否则对系统构成危险。因此,不可以如下编程:
40、因此,不可以如下编程:char*ps;scanf(%s,ps);而应写成:而应写成:char*ps,s10;ps=s;scanf(%s,ps);44字符数组名是指针常量,只能表示一个确定的字符串,不字符数组名是指针常量,只能表示一个确定的字符串,不能改变。而字符指针变量的值是可以改变的,它可以代表不能改变。而字符指针变量的值是可以改变的,它可以代表不同的字符串。同的字符串。若定义了一个指针变量,并使它指向一个字符串,就可以若定义了一个指针变量,并使它指向一个字符串,就可以用下标形式引用指针变量所指字符串中的字符。用下标形式引用指针变量所指字符串中的字符。如:如:char*a=I love Ch
41、ina!;printf(%c”,a5);若把字符指针所指对象当作数组使用,应注意对象的长度若把字符指针所指对象当作数组使用,应注意对象的长度 如:如:char str110,*ps=str1;ps10=0;45程序举例:将字符串程序举例:将字符串a复制为字符串复制为字符串b。#includemain()char a=It is a dog.,b20;int i=0;do *(b+i)=*(a+i);i+;while(*(a+i)!=0);/*也可写成也可写成while(*(a+i);*/puts(b);46上例程序还可写成:上例程序还可写成:#includemain()char a=It is
42、 a dog.,b20,*p1=a,*p2=b;int i=0;do *p2=*p1;p2+;p1+;while(*p1!=0);/*也可写成也可写成 while(*p1);*/puts(b);指针函数指针函数一、指针函数一、指针函数 返回指针的函数称作返回指针的函数称作指针函数指针函数。指针函数定义函数首部的一般形式指针函数定义函数首部的一般形式:类型名类型名 *函数名(参数表)函数名(参数表)含意:函数的返回值是一个指针,它指向所定含意:函数的返回值是一个指针,它指向所定 义类型的数据义类型的数据。例如:例如:int *a(int x,int y);/*函数原型声明函数原型声明*/含义:含
43、义:a是函数名,调用它以后能得到一个指向整型是函数名,调用它以后能得到一个指向整型数据的指针(地址)。数据的指针(地址)。48例例:编写能返回结果串地址的串拷贝函数。编写能返回结果串地址的串拷贝函数。#include char*strcpy1(char*str1,char*str2);main()char*ps,s180=yhhhj;ps=strcpy1(s1,fdgjdfh);puts(ps);char*strcpy1(char*str1,char*str2)char*s=str1;while(*str2)*str1+=*str2+;*str1=0;return s;53指针数组指针数组一、
44、指针数组一、指针数组 数组中每个元素是基类型相同指针变量。数组中每个元素是基类型相同指针变量。定义指针数组的一般形式定义指针数组的一般形式:类型标识符类型标识符*指针变量名指针变量名 常量表达式常量表达式;例如:例如:int*p2;含意:含意:p是一个一维指针数组,每个元素都是一个指是一个一维指针数组,每个元素都是一个指向整型变量的指针变量。可以将整型变量的地址赋向整型变量的指针变量。可以将整型变量的地址赋值给元素值给元素p0或或p1。54二、指针数组的应用二、指针数组的应用 利用指针数组处理多个串利用指针数组处理多个串 方法方法:先用指针数组指向字符数组:先用指针数组指向字符数组,再处理。再
45、处理。main()char name80=aaa,bbb,ccc,ddd,eee;char*pname10,i;for(i=0;i5;i+)pnamei=namei;for(i=0;i5;i+)puts(pnamei);方法方法:用指针数组指向字符串常量。:用指针数组指向字符串常量。main()char *pname10=aaa,bbb,ccc,ddd,eee;int i;for(i=0;i5;i+)puts(pnamei);55例题例题1:输入输入3个整数,按由小到大的顺序输出。个整数,按由小到大的顺序输出。#includevoid swap(int*p,int*q);main()int a
46、=9,b=7,c=10,*p1,*p2,*p3;p1=&a;p2=&b;p3=&c;if(*p1*p2)swap(p1,p2);if(*p1*p3)swap(p1,p3);if(*p2*p3)swap(p2,p3);printf(n%6d%6d%6d,*p1,*p2,*p3);void swap(int*p,int*q)int x;x=*p;*p=*q;*q=x;例题讲解例题讲解56例题例题2:输入输入3个字符串,按由小到大的顺序输出。个字符串,按由小到大的顺序输出。#includevoid swap(char*ps1,char*ps2);main()char s1=abc,s2=rst,s3
47、=xyz;if(strcmp(s1,s2)0)swap(s1,s2);if(strcmp(s1,s3)0)swap(s1,s3);if(strcmp(s2,s3)0)swap(s2,s3);printf(n%10s%10s%10s,s1,s2,s3);void swap(char*ps1,char*ps2)char ps100;strcpy(ps,ps1);strcpy(ps1,ps2);strcpy(ps2,ps);常用的字符串操作函数常用的字符串操作函数 58例题例题3:写一函数,实现两个字符串的比较。相等的结写一函数,实现两个字符串的比较。相等的结果为果为0,不等时结果为第一个不相等字符
48、的,不等时结果为第一个不相等字符的ASCII差值。差值。#includecmps(char*p,char*q);main()char s1128,s2128;gets(s1);gets(s2);printf(cmps(s1,s2)=%d,cmps(s1,s2);cmps(char*p,char*q)for(;*p!=0&*q!=0;p+,q+)if(*p!=*q)break;if(*p!=*q)return(*p-*q);else return 0;char*gets(char*);参数为从标准输入得到的字符参数为从标准输入得到的字符串存储的指针串存储的指针.返回值也是一个返回值也是一个指针指
49、针.如果函数执行失败返回值是一如果函数执行失败返回值是一个个NULL59例题例题4:写一个函数,求字符串的长度,在写一个函数,求字符串的长度,在main 函数中输入字符串,并输出其长度。函数中输入字符串,并输出其长度。#includeint len(char*ps);main()char str30;gets(str);printf(n len=%d,len(str);int len(char*ps)int n=0;while(*ps+)n+;return n;60例题例题5:有一字符串包含有一字符串包含N个字符,写一个函数,将个字符,写一个函数,将字符串中从第字符串中从第M个字符开始的全部字
50、符复制成为另个字符开始的全部字符复制成为另一个字符串。一个字符串。#include#includescopy(char*psn,char*psm,int m);main()char sn100=fasjfkjsdfsdfjsdjkfdfjssdf,sm100;int n=strlen(sn),m=n/2;scopy(sn,sm,m);printf(n sn=%s n m=%d n sm=%s,sn,m,sm);scopy(char*psn,char*psm,int m)while(*(psn+m)*psm+=*(m+psn+);*psm=0;例题例题6-1:求求a和和b中的大者中的大者-用函数