《《C语言第八章》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《C语言第八章》PPT课件.ppt(39页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第八章第八章 善于使用指针善于使用指针l主要内容什么是指针指针变量l定义、引用、和普通变量的关系l指针作为函数参数通过指针引用数组通过指针引用字符串l字符串指针作为函数参数提高部分18.1 什么是指针什么是指针l有关指针的一些概念指针:lC语言中,将地址形象化的称为指针通过指针找到数据,就是通过地址找到数据指针变量:l存放指针的变量,称之为指针变量指针变量里面存放的是指针,也就是地址为什么使用指针l更方便、更主动的操作数据、构建数据结构28.1 什么是指针什么是指针l学习指针的几点建议弄明白存放在内存中的数据是如何访问的l这是学习指针的基础清晰的记住指针和变量的几个关系:l指针的内容,指针指向
2、的内容等等明白指针作为函数参数、返回值的作用l将地址传递到函数,使得几个函数变量共同操作一个数据地址,实现数据交换38.1 什么是指针什么是指针l指针与地址存储器中的一个字节为一个单元,为了能够正确访问这些单元,必须为其编号。称之为地址所有数据都是存放在存储器中的。占据一个或多个单元。这些单元即数据在内存中的存放地址。一般来讲,一个数据是存放在多个连续的存储单元中的48.1 什么是指针什么是指针l指针与地址如果数据占据多个单元,一般的访问方式是,确定数据占据的单元数目,然后从其所占据单元的首地址开始依次访问指针变量存储的是数据占据单元的首地址,可以直接访问地址单元。指针变量若要访问存储的数据。
3、则需要知道数据的首地址和数据占据的空间指针变量的类型,就是数据占据的空间大小58.2 指针变量指针变量l8.2.1 使用指针变量的一个例子程序:void main()int a;int*p;/定义指针变量,变量前面加*a=100;p=&a;/将变量a的地址赋给指针pprintf(a=%dn,a);printf(*p=%dn,*p)/通过指针访问数据68.2 指针变量指针变量l8.2.2 指针变量的定义格式:类型说明符:*变量名“*”表示指针变量,说明这个变量是指针类型类型说明符:说明指针指向数据的类型若要改变指针指向的数据类型,则需要进行强制类型转换指针的值存放指向数据的首地址,指针的类型确定
4、了指向数据占据的单元数目78.2 指针变量指针变量l8.2.3 指针变量的引用变量的数据访问形式l普通变量:变量名变量存储的数据l指针变量:*变量名指向存储单元存储的数据定义时:*p表示为指针;使用时*p表示指针指向的数据变量的地址访问形式l普通变量:&变量名存储数据的首地址l指针变量:变量名指向的存储单元一般情况下,不要将地址值直接赋给指针变量88.2 指针变量指针变量l8.2.3 指针变量的引用一般情况下,不能将地址值直接赋给变量l若有 int a,*p;l则:&a=1000 p=2000是错误的指针不会单独使用,常和其他普通变量关联在一起使用l关联方式:p=&a l使用指针,必须要先给其
5、一个地址,再访问地址中的数据,如同使用变量必须有一个确定值一样98.2 指针变量指针变量l8.2.3 指针变量的引用指针和变量的几个换算关系:l对于变量,有:名称=数据、&名称=地址l对于指针,有:名称=地址、*名称=指向的数据l若有定义:int a,*p 则:&a、p 是同一类型数据,为地址a、*p 是同一类型数据,为整型数据l一般情况下,使用p=&ap=&a的形式,让指针与变量关联,使用*p的形式,访问指向的数据108.2 指针变量指针变量l8.2.4 指针变量作为函数参数复习:函数参数的传值与传址方式l传值:传递后形参不影响实参l传址:传递后实参、形参指向同一地址l利用传址的特点,改变形
6、参指针指向数据的内容,即可改变对应实参指针指向的内容l利用传址方式,可以让函数在保持独立性的同时,实现对主程序中的数据进行批量修改的功能。118.2 指针变量指针变量l8.2.4 指针变量作为函数参数指针作为函数参数,是一种传址方式。利用实参形参指向同一地址的特性,使函数可以改变上层函数中变量的值l使用这种方法,必须使用传址的特性,将要改变的变量的地址作为实参,传递给下层调用函数l函数的参数也必须为指针,通过在函数中改变指针指向的数据的值,就改变了实参指向数据的值,也就改变了实参所在函数中变量的值128.2 指针变量指针变量l8.2.4 指针变量作为函数参数例:用函数实现两个变量交换。l传值:
7、函数无法改变实参的值,不能实现l全局变量:可以实现,但函数独立性差函数的调用必须使用在函数之外定义的全局变量全局变量的定义必须符合函数要求的名称l传址:利用传址的特性,可以实现要求,同时保持了函数的独立性函数的参数必须是指针形参、实参的值均没有改变,改变的是地址中的值138.2 指针变量指针变量l8.2.4 指针变量作为函数参数例:用函数实现两个变量交换。l主程序void main()int a,b*pa,*pb;scanf(%d,%d,&a,&b);pa=&a;pb=&b;/指针pa指向变量a、pb指向变量bswap(pa,pb);/传递指针变量到函数printf(a=%d,b=%d,a,b
8、);148.2 指针变量指针变量l8.2.4 指针变量作为函数参数例:用函数实现两个变量交换。l变量交换函数void swap(int*p1,int*p2)int temp;/形参指针p1和实参指针pa的指向相同 /形参指针p2和实参指针pb的指向相同temp=*p1;/将p1指向地址的值存放到临时变量temp中*p1=*p2;/将p2指向地址的值放到p1指向的地址中*p2=temp;/将变量temp的值放到p2指向的地址中158.2 指针变量指针变量l8.2.4 指针变量作为函数参数168.3 通过指针引用数组通过指针引用数组l8.3.1 数组元素的指针指向数组元素的指针l将数组元素的地址赋
9、给指针若有int a5,*p 则可以:p=&a3l其使用和指向变量的指针没有区别指向数组的指针l指向数组首地址的指针,称为指向数组的指针l数组的名称,就是一个指向数组首地址的指针178.3 通过指针引用数组通过指针引用数组l8.3.2 通过指针引用数组元素指针的运算:仅有加减法运算l指针的算术运算,并非单纯的地址运算,而是同时涉及指针的地址、类型的一种运算l指针变量+1,是指指针指向的地址位置为下一个数下一个数据位。据位。l指针变量+1,要根据指针类型的长度来确定实际地址的增减量l即有(p+n)的地址=p的地址+sizeof(p的类型)*n188.3 通过指针引用数组通过指针引用数组l8.3.
10、2 通过指针引用数组元素指针的运算:仅有加减法运算l有如下定义:int a5,*p;p=a;l若p指向的地址为数组首地址2000Hl则p+1的地址为2000H+sizeof(int)*1sizeof(int)*1=2004H,不是单纯的2000H+1H=2001Hl同样:p+4的地址为2000H+sizeof(int)*4=2016H198.3 通过指针引用数组通过指针引用数组l8.3.2 通过指针引用数组元素数组元素的访问,就是通过对这个首地址进行计算,得到数组元素的确定位置后进行的访问数组元素的两种方式l数组变量引用:数组变量名下标l指针变量引用:*(指向数组的指针+下标)l对于数组a10
11、,若指针变量p=a,则有:a=&a0 *a=a0 a+5=&a5 *(a+5)=a5p=&a0 *p=a0 p+5=&a5 *(p+5)=a5208.3 通过指针引用数组通过指针引用数组l8.3.2 通过指针引用数组元素不同方式访问的程序int i,a5=6,7,8,9,0,*p=a;for(i=0;i5;i+)printf(a%d=%-4d,i,ai);printf(*(a+%d)=%-4d,i,*(a+i);printf(*(p+%d)=%-4d,i,*(p+i);printf(n);218.3 通过指针引用数组通过指针引用数组l8.3.2 通过指针引用数组元素指针运算的几个注意事项l指针
12、指向的地址,必须是程序已经申请的可用地址指针指向的地址,必须是程序已经申请的可用地址指向变量的指针,不能进行加减运算若指针指向数组,则可以进行加、减运算。运算的范围不能超出数组所在的地址区间若有a10,p=a;则p的运算范围为(p+0)-(p+9)若有a10,p=&a4;则p的运算范围为(p-4)-(p+5)l尽量不要改变指针存储的地址值(例8.7)对于指针p,其加减运算,应使用应使用(p+i)(p+i)而不是(p+)228.3 通过指针引用数组通过指针引用数组l8.3.3 使用数组名作为函数参数由于数组的名称是一个指针l所以原有的使用数组名作为函数参数,其本质是用指针作为函数参数传递数组到函
13、数,是传递数组的首地址到函数l实参:可以是数组名,也可以是指向数组的指针l形参:可以是数组名:访问时用数组名数组名下标下标的方式也可以是指针:访问时用(指针指针+变量变量)的方式238.3 通过指针引用数组通过指针引用数组l8.3.3 使用数组名作为函数参数指针与数组的一些总结l数组名称就是指针,不同点为:定义数组的时候,系统会根据数组的大小分配一段连续空间,并将这个空间的首地址赋给数组名称。指针定义后,并没有指向,必须赋值。只有让其指向数组,访问数组中的数据也必须限定范围l指针指向数组中的地址,通过加减就可以访问数组中的任何元素。指针可以不指向数组的首地址,从而实现对数组的一些特殊处理248
14、.3 通过指针引用数组通过指针引用数组l8.3.3 使用数组名作为函数参数l例子:若有数组打印函数void parr(int*p,int n)void main()int a10;parr(a,10);/打印数组parr(a,5);/打印数组的前5项parr(&a5,5);/打印数组的后5项parr(&a2,5);/打印数组的第3到7项258.4 通过指针引用字符串通过指针引用字符串l8.4.1 字符串的表示形式C语言中访问字符串的两种方法l使用字符数组:使用字符数组名的形式访问串使用(数组名下标)来访问、更改数组元素l使用字符类型的指针通过字符指针可以直接将字符串赋值给指针第一种方式:使字符
15、指针指向字符数组第二种方式:使用的形式,让指针指向字符串常量268.4 通过指针引用字符串通过指针引用字符串l8.4.1 字符串的表示形式字符类型指针的一些特点l是指针:存储的是内存中存放字符串区间的首地址可以使用*(指针+变量)的形式访问内部元素需要赋初值,让指针有明确的指向两个字符指针之间赋值,仅仅是将地址复制过去l若指向字符数组:用法和指向数组的指针相同可以使用给指针赋值。(数组首地址不可以用赋值)278.4 通过指针引用字符串通过指针引用字符串l8.4.2 字符指针作为函数参数字符类型指针的一些特点l若使用进行赋值,则是字符串常量:不可以更改其中单个字符的值可对整个字符串重新赋值l使用
16、使用赋值,指针变量指向的地址会发生变化赋值,指针变量指向的地址会发生变化每次对字符指针进行赋值,就是在内存中找到合适的空间存储串内的字符,然后再将首地址赋给字符指针变量此方式不必担心字符指针能够接受的字符串长度问题若字符指针指向数组后,再使用赋值,字符指针会得到一个新的地址,将不再指向数组将不再指向数组288.4 通过指针引用字符串通过指针引用字符串l8.4.2 字符指针作为函数参数是指针作为函数参数l实参可以是字符数组、字符指针和字符串常量通过函数改变的实参内容,一般为数组字符指针和字符串常量,仅仅是传递数据l形参是字符指针形参获得的是实参字符串的首地址,形参指向内容的改变,会影响到实参在函
17、数中,读取字符常量为实参的对应形参变量,写入字符数组为实参的对应形参变量298.4 通过指针引用字符串通过指针引用字符串l8.4.2 字符指针作为函数参数程序:复制字符串调用方式 strcopy(abc,s1)void strcopy(char*rp,char*wp)int i;for(i=0;*rp!=0;i+)*(wp+i)=*(rp+i);*(wp+i)=0;308.4 通过指针引用字符串通过指针引用字符串l8.4.3 字符数组与字符指针的异同差异原因:l字符数组名和字符指针均为指针l字符数组名指向确定容量、确定地址的内容空间l字符指针指向空间的容量、地址均不确定,可变更在定义时l均可用
18、给数组和字符指针赋初值l字符数组定义后,数组名指向确定的地址和空间l字符指针定义后无明确指向,必须初始化318.4 通过指针引用字符串通过指针引用字符串l8.4.3 字符数组与字符指针的异同在使用时:l数组的限制:字符数组是数组,而数组不能通过一次赋值批量更改多个元素,所以不能再使用进行赋值字符指针随时可以用进行赋值指向数组的指针,在使用进行赋值时,会指向新赋值的字符串常量。赋值并不能改变指针指向的数组中的元素值赋值后,指针指向字符串常量的地址,不再指向数组328.4 通过指针引用字符串通过指针引用字符串l8.4.3 字符数组与字符指针的异同在使用时:l字符指针的限制:字符指针指向的是字符常量
19、,不能单独更改其中某个字符的值,所以不能使用*(指针+变量)=x的形式写入字符字符数组可以改变其中任意元素的值字符指针可以接受新的字符常量,赋值后字符指针指向的地址都会发生变化l字符指针:最主要的用途就是为了有效的访问字符串常量,解决数组不能批量赋值的问题338.5 提高部分提高部分l8.5.2 多维数组的指针多维数组的存储方式348.5 提高部分提高部分l8.5.2 多维数组的指针多维数组的存储方式指向多维数组的指针l指针指向数组首地址l可以通过指针加减的方式访问其中的元素l若有定义 int a34,*p=a;则有:*p=a00 p=&a00有:*(p+1)=a01 *(p+6)=a12 有
20、:有:*(p+i*4+j)=aij(p+i*4+j)=aij358.5 提高部分提高部分l8.5.3 指向函数的指针函数的指针l每个函数在编译时,系统会给其分配一段存储空间l函数的指针,就是这段存储空间的首地址l这个首地址,也就是函数的入口指向函数的指针l通过赋值,指向函数的入口,就直接用指向函数的指针变量来调用函数l指向函数的指针,其主要是作为函数的参数出现368.5 提高部分提高部分l8.5.3 指向函数的指针函数作为函数的参数l函数本身,也可以作为另一个函数的参数l如一个排序函数,用一个比较函数作为它的参数,就可以针对不同的数据调用不同的比较函数指向函数的指针作为函数参数l使得函数可以调
21、用指针指向的函数l将函数的形参定义为指向函数的指针,则实参可以把不同的函数传递给形参指针,在函数内进行调用378.5 提高部分提高部分l8.5.4 返回指针的函数函数的返回值是指针l在定义函数时,需要在函数的名字前加上“*”l具体定义形式为:类型名*函数名(参数列表)l函数的返回值必须为类型相同的指针使用l返回的数据时字符串,需要给出一个首地址l申请存储空间的函数,成功后返回空间首地址388.5 提高部分提高部分l8.5.5 指针数组数组元素全部为指针l定义形式:类型名*数组名数组长度l数组中的每个元素都是指针l8.5.6 指向指针的指针指针指向的数据类型为指针l定义形式:类型名*变量名l例子:指向字符串的指针,指向指针数组的指针39