C语言程序设计C语言程序设计PPT (8).pdf

上传人:刘静 文档编号:57971160 上传时间:2022-11-06 格式:PDF 页数:83 大小:1.64MB
返回 下载 相关 举报
C语言程序设计C语言程序设计PPT (8).pdf_第1页
第1页 / 共83页
C语言程序设计C语言程序设计PPT (8).pdf_第2页
第2页 / 共83页
点击查看更多>>
资源描述

《C语言程序设计C语言程序设计PPT (8).pdf》由会员分享,可在线阅读,更多相关《C语言程序设计C语言程序设计PPT (8).pdf(83页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、8 8善 于 利 用 指 针第第章章指 针如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是“地址”。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化地称为“指针”。C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是“带类型的地址”。存储单元的地址和存储单元的内容是两个不同的概念。在程序中一般是通过变量名来引用变量的值。直接按变量名进行的访问,称为“直接访问”方式。还可以采用另一种称为“间接访问”的方式,即将变量

2、的地址存放在另一变量(指针变量)中,然后通过该指针变量来找到对应变量的地址,从而访问变量。int i=1,j=2,k=3;/设int变量占2字节变量名地址内容i200012003j200422007k200832011 指针变量使用指针变量的例子【例8.1】通过指针变量访问整型变量。#include int main()int a=100,b=10;/定义整型变量a,b,并初始化int*pointer_1,*pointer_2;/定义指向整型数据的指针变量pointer_1,pointer_2pointer_1=&a;/把变量a的地址赋给指针变量pointer_1pointer_2=&b;/把

3、变量b的地址赋给指针变量pointer_2 printf(a=%d,b=%dn,a,b);/输出变量a和b的值printf(*pointer_1=%d,*pointer_2=%dn,*pointer_1,*pointer_2);/输出变量a和b的值return 0;pointer_1a&a100*pointer_1pointer_2b&b10*pointer_2注意定义指针变量时,左侧应有类型名,否则就不是定义指针变量。*pointer_1;/企图定义pointer_1为指针变量。出错int*pointer_1;/正确,必须指定指针变量的基类型怎样定义指针变量类型名*指针变量名;int*poi

4、nter_1,*pointer_2;左端的int是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型。前面介绍过基本的数据类型(如int,char,float等),既然有这些类型的变量,就可以有指向这些类型变量的指针,因此,指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。在定义指针变量时要注意:(1)指针变量前面的“*”表示该变量为指针型变量。指针变量名则不包含“*”。(2)在定义指针变量时必须指定基类型。一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如i

5、nt,char,float等)。(3)如何表示指针类型。指向整型数据的指针类型表示为“int*”,读作“指向int的指针”或简称“int指针”。(4)指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量。怎样引用指针变量 给指针变量赋值。引用指针变量指向的变量。引用指针变量的值。int a,*p;p=&a;/把a的地址赋给指针变量pprintf(%d,*p);/以整数形式输出指针变量p所指向的变量的值,即a的值*p=1;/将整数1赋给p当前所指向的变量,由于p指向变量a,相当于把1赋给a,即a=1printf(%o,p);/以八进制形式输出指针变量p的值,由于p指向a,相当于输出a的

6、地址,即&a注意要熟练掌握两个有关的运算符:(1)取地址运算符。&a是变量a的地址。(2)*指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象。怎样引用指针变量【例8.2】输入a和b两个整数,按先大后小的顺序输出a和b。#include int main()int*p1,*p2,*p,a,b;/p1,p2的类型是int*类型printf(please enter two integer numbers:);scanf(%d,%d,&a,&b);/输入两个整数p1=&a;/使p1指向变量ap2=&b;/使p2指向变量bif(ab)/如果abp=p1;p1=p2;p2=p;/使p1

7、与p2的值互换printf(a=%d,b=%dn,a,b);/输出a,bprintf(max=%d,min=%dn,*p1,*p2);/输出p1和p2所指向的变量的值return 0;注意a和b的值并未交换,它们仍保持原值,但p1和p2的值改变了。实际上,第9行可以改为p1=&b;p2=&a;即直接对p1和p2赋以新值,这样可以不必定义中间变量p,使程序更加简练。解题思路:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)。p1a&a 5p2b&b 9p交换前交换后p1a&b5p2b&a9p指针变量作为函数参数【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函

8、数处理,而且用指针类型的数据作函数参数。#include int main()void swap(int*p1,int*p2);/对swap函数的声明int a,b;int*pointer_1,*pointer_2;/定义两个int*型的指针变量printf(please enter a and b:);scanf(%d,%d,&a,&b);/输入两个整数pointer_1=&a;/使pointer_1指向apointer_2=&b;/使pointer_2指向b if(ab)swap(pointer_1,pointer_2);/如果ab,调用swap函数printf(max=%d,min=%d

9、n,a,b);/输出结果return 0;void swap(int*p1,int*p2)/定义swap函数int temp;temp=*p1;/使*p1和*p2互换*p1=*p2;*p2=temp;/本例交换a和b的值,而p1和p2的值不变。这恰和例8.2相反pointer_1a&a5pointer_2b&b9p1&aapointer_15&apointer_1a&a9pointer_2b&b5p1&aapointer_19&ap2&bbpointer_29&bp2&bbpointer_25&b指针变量作为函数参数【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函数处理

10、,而且用指针类型的数据作函数参数。void swap(int*p1,int*p2)/定义swap函数int temp;temp=*p1;/使*p1和*p2互换*p1=*p2;*p2=temp;void swap(int*p1,int*p2)int*temp;*temp=*p1;*p1=*p2;*p2=*temp;*p1就是a,是整型变量。而*temp是指针变量temp所指向的变量。但由于未给temp赋值,因此temp中并无确定的值(它的值是不可预见的),所以temp所指向的单元也是不可预见的。所以,对*temp赋值就是向一个未知的存储单元赋值,而这个未知的存储单元中可能存储着一个有用的数据,这

11、样就有可能破坏系统的正常工作状况。void swap(int x,int y)int temp;temp=x;x=y;y=temp;在函数调用时,a的值传送给x,b的值传送给。执行完swap函数后,x和y的值是互换了,但并未影响到a和b的值。在函数结束时,变量x和y释放了,main函数中的a和b并未互换。ab5959xyab5995xy指针变量作为函数参数函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。要善于利用指针法。如果想通过函数调用得到n个要改变的值,可以这样做:在主调函数中设n个变量,用n个指针变

12、量指向它们;设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值;在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的值,也就是相关变量的地址传给该函数的形参;在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值;主调函数中就可以使用这些改变了值的变量。指针变量作为函数参数【例8.4】对输入的两个整数按大小顺序输出。#include int main()void swap(int*p1,int*p2);int a,b;int*pointer_1,*pointer_2;/pointer_1,pointer_2是int*型变量printf(please ent

13、er two integer numbers:);scanf(%d,%d,&a,&b);pointer_1=&a;pointer_2=&b;if(ab)swap(pointer_1,pointer_2);/调用swap函数,用指针变量作实参printf(max=%d,min=%dn,*pointer_1,*pointer_2);return 0;void swap(int*p1,int*p2)/形参是指针变量int*p;p=p1;/下面3行交换p1和p2的指向p1=p2;p2=p;pointer_1a&a5pointer_2b&b9不能企图通过改变指针形参的值而使指针实参的值改变p1a&a5p

14、2b&b9p1a&b5p2b&a9pointer_1a&a5pointer_2b&b9指针变量作为函数参数【例8.5】输入3个整数a,b,c,要求按由大到小的顺序将它们输出。用函数实现。#include int main()void exchange(int*q1,int*q2,int*q3);/函数声明int a,b,c,*p1,*p2,*p3;printf(please enter three numbers:);scanf(%d,%d,%d,&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);printf(The order is:%d,%d,%

15、dn,a,b,c);return 0;void exchange(int*q1,int*q2,int*q3)/将3个变量的值交换的函数void swap(int*pt1,int*pt2);/函数声明if(*q1*q2)swap(q1,q2);/如果ab,交换a和b的值if(*q1*q3)swap(q1,q3);/如果ac,交换a和c的值if(*q2*q3)swap(q2,q3);/如果bc,交换b和c的值void swap(int*pt1,int*pt2)/交换2个变量的值的函数int temp;temp=*pt1;/交换*pt1和*pt2变量的值*pt1=*pt2;*pt2=temp;通过指

16、针引用数组数组元素的指针一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。引用数组元素可以用下标法,也可以用指针法,即通过指向数组元素的指针找到所需的元素。在定义指针变量时可以对它初始化:int a10=1,3,5,7,9,11,13,15,17,19;/定义a为包含10个整型数据的数组int*p;/定义p为指向整型变量的指针变量p=&a0;/把a0元素的地址赋给指针变量pp&a01a035

17、791113151719p=&a0;/p的值是a0的地址p=a;/p的值是数组a首元素(即a0)的地址注意程序中的数组名不代表整个数组,只代表数组首元素的地址。int*p=&a0;int*p;p=&a0;/不应写成*p=&a0;int*p=a;在引用数组元素时指针的运算在指针已指向一个数组元素时,可以对指针进行以下运算:加一个整数(用+或+=),如p+1,表示指向同一数组中的下一个元素;减一个整数(用-或-=),如p-1,表示指向同一数组中的上一个元素;自加运算,如p+,+p;自减运算,如p-,-p。两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义),结果是两个地址之

18、差除以数组元素的长度。注意:两个地址不能相加,如p1+p2是无实际意义的。如果p的初值为&a0,则p+i和a+i就是数组元素ai的地址,或者说,它们指向a数组序号为i的元素。*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即ai。实际上是变址运算符,即将ai按a+i计算地址,然后找出此地址单元中的值。注意执行p+1时并不是将p的值(地址)简单地加1,而是根据定义的基类型加上一个数组元素所占用的字节数。pa数组p+1,a+1a0a1a2p+i,a+i*(p+i)aip+9,a+9a9通过指针引用数组元素【例8.6】有一个整型数组a,有10个元素,要求输出数组中的全部元素。#inclu

19、de int main()int a10;int i;printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;i10;i+)printf(%d,ai);/数组元素用数组名和下标表示printf(%n);return 0;下标法#include int main()int a10;int i;printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,&ai);for(i=0;i10;i+)printf(%d,*(a+i);/通

20、过数组名和元素序号计算元素地址找到该元素printf(n);return 0;通过数组名计算数组元素地址,找出元素的值#include int main()int a10;int*p,i;printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,&ai);for(p=a;p(a+10);p+)printf(%d,*p);/用指针指向当前的数组元素printf(n);return 0;用指针变量指向数组元素第(1)和第(2)种方法执行效率是相同的。C编译系统是将ai转换为*(a+i)处理的,即先计算元素地址。因此用第(1)和

21、第(2)种方法找数组元素费时较多。第(3)种方法比第(1)、第(2)种方法快,用指针变量直接指向元素,不必每次都重新计算地址,像p+这样的自加操作是比较快的。这种有规律地改变地址值(p+)能大大提高执行效率。通过指针引用数组元素用下标法比较直观,能直接知道是第几个元素。适合初学者使用。用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。单用指针变量的方法进行控制,可使程序简洁、高效。注意在使用指针变量指向数组元素时,有以下几个问题要注意:(1)可以通过改变指针变量的值指向不同的元素。如果不用p变化的方法而用数组名a变化的方法(例如,用a+)行不行呢?因为数组名a代表数组首元

22、素的地址,它是一个指针型常量,它的值在程序运行期间是固定不变的。既然a是常量,所以a+是无法实现的。(2)要注意指针变量的当前值。for(p=a;a(p+10);a+)printf(%d,*a);通过指针引用数组元素【例8.7】通过指针变量输出整型数组a的10个元素。#include int main()int*p,i,a10;p=a;/p指向a0printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,p+);/输入10个整数给a0a9for(i=0;i10;i+,p+)printf(%d,*p);/想输出a0a9 pr

23、intf(n);return 0;#include int main()int i,a10,*p=a;/p的初值是a,p指向a0printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,p+);p=a;/重新使p指向a0for(i=0;i10;i+,p+)printf(%d,*p);printf(n);return 0;pa数组a0pa9通过指针引用数组元素(1)从例8.7可以看到,虽然定义数组时指定它包含10个元素,并用指针变量p指向某一数组元素,但是实际上指针变量p可以指向数组以后的存储单元,结果不可预期,应避免出现这

24、样的情况。(2)指向数组元素的指针变量也可以带下标,如pi。pi被处理成*(p+i),如果p是指向一个整型数组元素a0,则pi代表ai。但是必须弄清楚p的当前值是什么?如果当前p指向a3,则p2并不代表a2,而是a3+2,即a5。(3)利用指针引用数组元素,比较方便灵活,有不少技巧。请分析下面几种情况:设p开始时指向数组a的首元素(即p=a):如果p当前指向a数组中第i个元素ai,则:p+;/使p指向下一元素a1*p;/得到下一个元素a1的值*p+;/*由于+和*同优先级,结合方向自右而左,因此它等价于*(p+)。先引用p的值,实现*p的运算,然后再使p自增1*/*(p+);/先取*p值,然后

25、使p加1*(+p);/先使p加1,再取*p+(*p);/*表示p所指向的元素值加1,如果p=a,则相当于+a0,若a0的值为3,则a0的值为4。注意:是元素a0的值加1,而不是指针p的值加1*/*(p-)/相当于ai-,先对p进行“*”运算,再使p自减*(+p)/相当于a+i,先使p自加,再进行“*”运算*(-p)/相当于a-i,先使p自减,再进行“*”运算用数组名作函数参数void fun(int*arr,int n)/定义fun函数int main()void fun(int arr,int n);/对fun函数的声明int array10;/定义array数组fun(array,10);

26、/用数组名作函数的参数return 0;void fun(int arr,int n)/定义fun函数array是实参数组名,arr为形参数组名。当用数组名作参数时,如果形参数组中各元素的值发生变化,实参数组元素的值随之变化。arrayarrarray0arr0arr+3array3arr3在该函数被调用时,系统会在fun函数中建立一个指针变量arr,用来存放从主调函数传递过来的实参数组首元素的地址。如果在fun函数中用运算符sizeof测定arr所占的字节数,可以发现sizeof(arr)的值为4(用Visual C+时)。这就证明了系统是把arr作为指针变量来处理的(指针变量在Visual

27、 C+中占4个字节)。当arr接收了实参数组的首元素地址后,arr就指向实参数组首元素,也就是指向array0。用数组名作函数参数以变量名和数组名作为函数参数的比较C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。在函数调用进行虚实结合后,形参的值就是实参数组首元素的地址。在函数执行期间,它可以再被赋值。实参类型变量名数组名要求形参的类型变量名数组名或指针变量传递的信息变量的值实参数组首元素的地址通过函数调用能否改变实参的值不能改变实参变量的值能

28、改变实参数组的值注意实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理。void fun(arr,int n)printf(%dn,*arr);/输出array0的值arr=arr+3;/形参数组名可以被赋值printf(%dn,*arr);/输出array3的值用数组名作函数参数【例8.8】将数组a中n个整数按相反顺序存放。#include int main()void inv(int x,int n);/inv函数声明int i,a10=3,7,9,11,0,6,7,5,4,2;printf(The original array:n);fo

29、r(i=0;i10;i+)printf(%d,ai);/输出未交换时数组各元素的值printf(n);inv(a,10);/调用inv函数,进行交换printf(The array has been inverted:n);for(i=0;i10;i+)printf(%d,ai);/输出交换后数组各元素的值printf(n);return 0;void inv(int x,int n)/形参x是数组名int temp,i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;/把xi和xj交换return;37911067542imj

30、24576011973#include int main()void inv(int*x,int n);int i,a10=3,7,9,11,0,6,7,5,4,2;printf(The original array:n);for(i=0;i10;i+)printf(%d,ai);printf(n);inv(a,10);printf(The array has been inverted:n);for(i=0;i10;i+)printf(%d,ai);printf(n);return 0;void inv(int*x,int n)/形参x是指针变量int*p,temp,*i,*j,m=(n-1

31、)/2;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;/*i与*j交换return;i,xa数组3a07a19a2p=x+m11a30a46a57a65a7j4a82a9用数组名作函数参数如果有一个实参数组,要想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下4种情况。形参和实参都用数组名 实参用数组名,形参用指针变量。实参形参都用指针变量。实参为指针变量,形参为数组名。int main()int a10;f(a,10);int f(int x,int n)int main()int a10;f(a,10);int f(

32、int*x,int n)int main()int a10;*p=a;f(p,10);int f(int*x,int n)int main()int a10;*p=a;f(p,10);int f(int x,int n)用数组名作函数参数【例8.9】改写例8.8,用指针变量作实参。#include int main()void inv(int*x,int n);/inv函数声明int i,arr10,*p=arr;/指针变量p指向arr0printf(The original array:n);for(i=0;i10;i+,p+)scanf(%d,p);/输入arr数组的元素printf(n)

33、;p=arr;/指针变量p重新指向arr0inv(p,10);/调用inv函数,实参p是指针变量printf(The array has been inverted:n);for(p=arr;parr+10;p+)printf(%d,*p);printf(n);return 0;void inv(int*x,int n)/定义inv函数,形参x是指针变量int*p,m,temp,*i,*j;m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;return;#include int main()void inv(int

34、*x,int n);/inv函数声明int i,*arr;/指针变量arr未指向数组元素printf(The original array:n);for(i=0;i10;i+)scanf(%d,arr+i);printf(n);inv(arr,10);/调用inv函数,实参arr是指针变量,但无指向printf(The array has been inverted:n);for(i=0;i10;i+)printf(%d,*(arr+i);printf(n);return 0;注意如果用指针变量作实参,必须先使指针变量有确定值,指向一个已定义的对象。用数组名作函数参数【例8.10】用指针方法对

35、10个整数按由大到小顺序排序。(选择排序法)#include int main()void sort(int x,int n);/sort函数声明int i,*p,a10;p=a;/指针变量p指向a0printf(please enter 10 integer numbers:);for(i=0;i10;i+)scanf(%d,p+);/输入10个整数p=a;/指针变量p重新指向a0sort(p,10);/调用sort函数for(p=a,i=0;i10;i+)printf(%d,*p);/输出排序后的10个数组元素p+;printf(n);return 0;void sort(int x,in

36、t n)/定义sort函数,x是形参数组名int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jxk)k=j;if(k!=i)t=xi;xi=xk;xk=t;void sort(int*x,int n)/形参x是指针变量int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;j*(x+k)k=j;/*(x+j)就是xj,其他亦然if(k!=i)t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;*通过指针引用多维数组多维数组元素的地址a0a0+1a0+2a0+3aa0a00a01a02a032000200420082012

37、a+1a113572016202020242028a+2a29111315203220362040204417192123int a34=1,3,5,7,9,11,13,15,17,19,21,23;表示形式含义地址a二维数组名,指向一维数组a0,即0行起始地址2000a0,*(a+0),*a0行0列元素地址2000a+1,&a1指向第1行起始地址2016a1,*(a+1)1行0列元素a10的地址2016a1+2,*(a+1)+2,&a121行2列元素a12的地址2024*(a1+2),*(*(a+1)+2),a121行2列元素a12的值是元素值,为13多维数组元素的地址C语言的地址信息中既包

38、含位置信息(如内存编号2000),还包含它所指向的数据的类型信息。a0是一维数组名,它是一维数组中起始元素的地址,a是二维数组名,它是二维数组的首行起始地址,二者的纯地址是相同的,即2000,但它们的基类型不同,即它们指向的数据的类型不同,前者是整型数据,后者是一维数组。如果用一个指针变量pt来指向此一维数组,应当这样定义:int(*pt)4;/表示pt指向由4个整型元素组成的一维数组,此时指针变量pt的基类型是由4个整型元素组成的一维数组多维数组元素的地址【例8.11】输出二维数组的有关数据(地址和元素的值)。#include int main()int a34=1,3,5,7,9,11,1

39、3,15,17,19,21,23;printf(%d,%dn,a,*a);/0行起始地址和0行0列元素地址printf(%d,%dn,a0,*(a+0);/0行0列元素地址printf(%d,%dn,&a0,&a00);/0行起始地址和0行0列元素地址printf(%d,%dn,a1,a+1);/1行0列元素地址和1行起始地址printf(%d,%dn,&a10,*(a+1)+0);/1行0列元素地址printf(%d,%dn,a2,*(a+2);/2行0列元素地址printf(%d,%dn,&a2,a+2);/2行起始地址printf(%d,%dn,a10,*(*(a+1)+0);/1行0列

40、元素的值printf(%d,%dn,*a2,*(*(a+2)+0);/2行0列元素的值return 0;指向数组元素的指针变量【例8.12】有一个34的二维数组,要求用指向元素的指针变量输出二维数组各元素的值。#include int main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int*p;/p是int*型指针变量for(p=a0;pa0+12;p+)/使p依次指向下一个元素if(p-a0)%4=0)printf(n);/p移动4次后换行printf(%4d,*p);/输出p指向的元素的值printf(n);return 0;p是一个int*型(指

41、向整型数据)的指针变量,它可以指向一般的整型变量,也可以指向整型的数组元素。每次使p值加1,使p指向下一元素。如果要输出某个指定的数值元素(例如a23),则应事先计算该元素在数组中的相对位置(即相对于数组起始位置的相对位移量)。计算aij在数组中的相对位置的计算公式为:i*mj,其中,m为二维数组的列数(二维数组大小为nm)。mni=2a23j=3指向由m个元素组成的一维数组的指针变量【例8.13】输出二维数组任一行任一列元素的值。#include int main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;/定义二维数组a并初始化int(*p)4,i,j

42、;/指针变量p指向包含4个整型元素的一维数组p=a;/p指向二维数组的0行printf(please enter row and colum:);scanf(%d,%d,&i,&j);/输入要求输出的元素的行列号printf(a%d,%d=%dn,i,j,*(*(p+i)+j);/输出aij的值return 0;比较:int a4;(a有4个元素,每个元素都为整型)int(*p)4;第种形式表示p所指的对象是有4个整型元素的一维数组。应该记住,此时p只能指向一个包含4个元素的一维数组,不能指向一维数组中的某一元素。p的值是该一维数组的起始地址。虽然这个地址(指纯地址)与该一维数组首元素的地址相

43、同,但它们的基类型是不同的。*p(数组)p(*p)0(*p)1(*p)2(*p)3#include int main()int a4=1,3,5,7;/定义一维数组a,包含4个元素int(*p)4;/定义指向包含4个元素的一维数组的指针变量p=&a;/使p指向一维数组printf(%dn,(*p)3);/输出a3,输出整数7return 0;指向由m个元素组成的一维数组的指针变量要注意指针变量的类型,从“int(*p)4;”可以看到,p的类型不是int*型,而是int(*)4型,p被定义为指向一维整型数组的指针变量,一维数组有4个元素,因此p的基类型是一维数组,其长度是16字节。“*(p+2)

44、+3”括号中的2是以p的基类型(一维整型数组)的长度为单位的,即p每加1,地址就增加16个字节(4个元素,每个元素4个字节),而“*(p+2)+3”括号外的数字3,不是以p的基类型的长度为单位的。由于经过*(p+2)的运算,得到a2,即&a20,它已经转化为指向列元素的指针了,因此加3是以元素的长度为单位的,加3就是加(34)个字节。虽然p+2和*(p+2)具有相同的值,但由于它们所指向的对象的长度不同,因此(p+2)+3和*(p+2)+3的值就不相同了。用指向数组的指针作函数参数一维数组名可以作为函数参数,多维数组名也可作函数参数。用指针变量作形参,以接受实参数组名传递来的地址。可以有两种方

45、法:用指向变量的指针变量;用指向一维数组的指针变量。用指向数组的指针作函数参数【例8.14】有一个班,3个学生,各学4门课,计算总平均分数以及第n个学生的成绩。#include int 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,2);/求序号为2的学生的成绩return 0;void average(float*p,int

46、n)/定义求平均成绩的函数float*p_end;float sum=0,aver;p_end=p+n-1;/n的值为12时,p_end的值是p+11,指向最后一个元素for(;p=p_end;p+)sum=sum+(*p);aver=sum/n;printf(average=%5.2fn,aver);void search(float(*p)4,int n)/p是指向具有4个元素的一维数组的指针int i;printf(The score of No.%d are:n,n);for(i=0;i4;i+)printf(%5.2f,*(*(p+n)+i);printf(n);注意实参与形参如果是

47、指针类型,应当注意它们的基类型必须一致。不应把int*型的指针(即数组元素的地址)传给int(*)4 型(指向一维数组)的指针变量,反之亦然。用指向数组的指针作函数参数【例8.15】在例8.14的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#include int main()void search(float(*p)4,int n);/函数声明float score34=65,57,70,60,58,87,90,81,90,99,100,98;/定义二维数组函数scoresearch(score,3);/调用search函数return 0;void search(fl

48、oat(*p)4,int n)/形参p是指向包含4个float型元素的一维数组的指针变量int i,j,flag;for(j=0;jn;j+)flag=0;for(i=0;i4;i+)if(*(*(p+j)+i)60)flag=1;/*(*(p+j)+i)就是scorejiif(flag=1)printf(No.%d fails,his scores are:n,j+1);for(i=0;i4;i+)printf(%5.1f,*(*(p+j)+i);/输出*(*(p+j)+i)就是输出scoreji的值printf(n);通过指针引用字符串字符串的引用方式(1)用字符数组存放一个字符串,可以通

49、过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明“%s”输出该字符串。(2)用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。字符串的引用方式【例8.16】定义一个字符数组,在其中存放字符串I love China!,输出该字符串和第8个字符。【例8.17】通过字符指针变量输出一个字符串。#include int main()char string=I love China!;/定义字符数组stingprintf(%sn,string);/用%s格式声明输出string,可以输出整个字符串printf(%cn,string7);/用%c格式输出一个字符数组元素re

50、turn 0;#include int main()char*string=I love China!;/定义字符指针变量string并初始化printf(%sn,string);/输出字符串return 0;stringIstring0string1lstring2ostring3vstring4estring5string(7)string6Cstring7hstring8istring9nstring10astring11!string120 string13stringIloveChina!0字符串的引用方式在C语言中只有字符变量,没有字符串变量。可以对指针变量进行再赋值,如:可以通过

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com