C语言第10章(谭浩强).ppt

上传人:xin****828 文档编号:15470854 上传时间:2020-08-12 格式:PPT 页数:80 大小:413.50KB
返回 下载 相关 举报
C语言第10章(谭浩强).ppt_第1页
第1页 / 共80页
C语言第10章(谭浩强).ppt_第2页
第2页 / 共80页
C语言第10章(谭浩强).ppt_第3页
第3页 / 共80页
点击查看更多>>
资源描述
1,第10章 指针,指针可以有效地表示复杂的数据结构;能动态的分配内存、使用字符串和数组;能在调用函数时获得1个以上的结果;能直接处理内存单元地址等。 掌握指针的应用,可以使程序简洁、紧凑、高效。,2,10.1 地址和指针的概念 一、变量的地址 计算机内存区的每一个字节都有一个编号。 在对程序进行编译时,系统会给变量分配内存单元,这个内存单元的地址就是变量的地址。系统根据不同的数据类型分配不同字节的空间。,内存单元地址 内存单元内容 不同,编译时是把变量名转换为变量的地址 如: scanf(“%d” , ,3,二、变量的访问方式 1.直接访问 按变量地址存取变量值的方式称为“直接访问” 方式。 2.间接访问 假如定义变量j 存放变量i的地址。,如: j = ,4,三、指针变量 由于通过地址可以找到所需变量的存储单元,所以c语言把地址称为指针。 指针:一个变量的地址称为该变量的指针。 例如:地址2000是变量i的指针。 指针变量:专门存放变量地址的变量叫指针变量。 注意:指针和指针变量的区别 如:j 为指针变量,它存放整型变量i的地址 我们称,指针变量 j 指向整型变量i,5,10.2 变量的指针和指向变量的指针变量 变量的指针就是变量的地址。 存放变量地址的变量是指针变量,用来指向另一个变量。,6,注意:在c程序中用*表示指向,若定义了i_pointer为指针变量,那么*i_pointer就是i_pointer指向的那个变量。*i_pointer 相当于 i 都代表 3(值),/* 指针i_pointer指向了变量i */,一 、如何定义一个指针变量 形式:基类型 *指针变量名 指针只能指向基类型规定的类型变量 例如:int i , j ; float x ; int *i_pointer , *j_pointer ; 那么,如何使一个指针变量指向另一个变量呢? 可以: i = 3 ; i_pointer = ,7,在定义指针变量时注意:,(1)定义指针变量时,变量前面的*是表示该变量是指针型的,其变量名是i_pointer,而不是* i_pointer (2)定义指针变量必须指定其类型。为什么? 当i_pointer+时,加1代表多少字节才能确定。 总结:一个指针变量只能指向同一类型的变量。 如: float a ; int *pointer ; pointer = (错),8,二、 指针变量的引用指针变量中只能存放地址(指针),两个运算符: 1. ,强调*定义和引用时的区别,9,输出:100,10 100,10,*pointer_1 = ,例10.1 通过指针变量访问整型变量 main() int a,b; int *pointer_1, *pointer_2 ; /*区分定义和引用时的区别*/ a=100 ; b=10 ; pointer_1 = ,10,说明: 若: p1 = p2= scanf(“%d,%d”, ,13,三、 指针变量作为函数参数 函数的参数可以是整型、实型、字符型等数据或者是数组,还可以是指针类型的。它的作用是将一个变量的地址传送到另一个函数中。,14,例10.3 同例10.2输入a和b两个整数,按大小的顺序输出.,main( ) int *p1 , *p2 , a , b ; scanf (“%d,%d”, ,void swap(int *p1,int *p2) int temp; temp = *p1 ; *p1 = *p2 ; *p2 = temp ; ,/*指针变量作函数参数,把变量a和b的地址传给形参,这时实参和形参都指向变量a和b */,/* 定义形参,所以要带* */,/*把变量a和b的值交换*/,注意:a和b的值改变了。,15,指针变量作函数参数时,注意: 1.指针变量,既可以作为函数的形参,也可以作函数的实参。 2.指针变量作实参时,与普通变量一样,也是“值传递”,即将指针变量的值(一个地址)传递给被调用函数的形参(必须是一个指针变量)。 注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。,16,例10.4 输入a、b、c 3个整数,按大小顺序输出。,void swap(int *pt1,int *pt2) /*指针变量作函数形数*/ int temp; temp = *pt1 ; *pt1 = *pt2 ; *pt2 = temp ; /*交换变量*/,void exchange(int *q1,int *q2,int *q3) /*判断大小*/ if (*q1*q2) swap (q1,q2) ; /*指针变量作函数实参*/ if (*q1*q3) swap (q1,q3) ; if (*q2*q3) swap(q2,q3) ; ,main() int a , b , c , *p1 , *p2 , *p3 ; scanf (“%d,%d,%d”, ,17,10.3 数组的指针和指向数组的指针变量,既然指针可以指向变量,当然也能指向数组。 数组的元素是连续存放的: 一般,用下标法表示数组元素,如:a3,10.3.1 指向数组元素的指针 如何定义指向数组的指针变量? 定义与指向普通变量的指针变量的定义方法一样。 例如: int a10 , *pointer = a ; 或者: int a10 , *pointer ; pointer = a ; 以上是在语句中赋值,分为两步。, int a5 = 2,4,8,16,32 ; p1 = ,2,4,8,16,32,a0,a1,a2,a3,a4,p1,p2,p3,19,10.3.2 通过指针引用数组元素 如: int a3 , *p = a ; *p = 1 ; /*相当于a0=1 */ ( p = 1 ; ) (错) 注意:当p+1时,则指针p指向同一数组的下一个元素,而不是把地址加1。 当p为int型时:p+1相当于使p的值(地址)加2个字节; 当p为float型时:p+1相当于使p的值(地址)加4个字节; 所以: p+1代表的地址 = p+1*d,/* d为数组元素的类型所占的字节数 */,20,说明: 如果有 int a10 , *p = a ; ,则: (1)p+i 和 a+i 都可以表示数组元素 ai 的地址,或者说它们都指向a数组的第i个元素。 例如: p+9 a+9 (2) *(p+i) 和 *(a+i) 就是数组元素 ai 的值。 例如: *(p+5) *(a+5),值都是 for(i=0; i10; i+) scanf(“%d”, ,(3)用指针变量指向数组元素 void main() int a10, i,*p; for(i=0; i10; i+) scanf(“%d”, ,(2)用数组名计算数组地址,找到元素的值 void main() int a10, i; for(i=0; i10; i+) scanf(“%d”, ,第1、2种方法效率相同,第3种方法的效率更高,for( i=0,p=a; p(a+10); p+ ) printf(%d , pi );,23,使用指针变量指向数组元素时,需注意: (1)可以通过改变指针变量的值使其指向不同的元素, 如 p+ 但是不能用数组名 a+ (2)使用指针变量,要注意指针的当前值。如下例,main() int *p , i , a5; p = a ; for(i=0;i5;i+) scanf(“%d”, p+ ); printf(“n”);,for(i=0; i5 ; i+ , p+ ) printf(“%d”, *p ); printf(“n”); ,p = a;,/*输出数组元素*/,解决办法:?,(3)由上例得出,指针变量可以指向数组以外的内存单元,系统不会报错。,24,*(p+) a0 *(+p) a1,若 p a0,则,注意: (4)指针变量的运算。 p = a ; /*指针p指向了数组a的首地址*/ 1) p+ /*使p指向下一个元素*/ 2)*p+ *(p+) /*先得到*p的值,指针p指向下一地址*/ 如:for( i=0;i5;i+,p+) printf(“%d”, *p ); 3)*(p+) 与 *(+p) 不同,可改为: for( i=0 ; i5 ; i+ ) printf(“%d”, *p+ );,25,4)+ (*p) /* p指向的值加1 */ 若 p a0 , a0=5 , 则 +(*p) a0=6 5)若 p ai ,则: *(p-) ai- /* 先做*p运算,p再自减 */ *(-p) a-i /* 先做p自减,再做*运算 */ *(+p) a+i同理,26,6)指针的关系运算 若两个指针指向同一个数组的元素,则可以进行关系运算,运算结果为0或1。 、= :判断两个指针指向的数据位置的前后关系 =,!= :判断两个指针是否指向同一个数据 7)指针变量可以有空值,即该指针变量不指向任 何变量。 p = NULL ;,27,10.3.3 用数组名作函数参数 数组名作实参时:起始地址 形参数组; 数组名作形参时:接收实参数组的起始地址 实际上,c编译是把形参数组名作为指针变量来处理。 如: f( int a , int n ) f( int *a , int n ),等价,28,例10.7 请把数组a中的n个元素按相反的顺序存放。,算法:a0 an-1 a1 an-2 aint (n-1)/2 an- int(n-1) /2) -1,设循环变量i,j i=0;j=n-1 ai aj 交换 ;直到i=(n-1)/2。,i: 0 (n-1)/2 (n-1) : j-,29,main() int i,a10 = 3,5,2,6,8,9,0,1,7,4 ; for( i=0 ; i10 ; i+ ) printf(%d,ai); printf(n); inv ( a , 10 ) ; /*数组名a作实参*/ for( i=0;i10;i+ ) printf(%d“ , ai ) ; ,程序:,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 ; ,void inv (int * x , int n) /*指针变量x作形参*/ int temp ,* i , * j , *p , m = (n-1)/2 ; i = x ; j= x+n-1 ; p =x+m ; for( ; i = p ; i+ ,j-) temp = *i ; *i = *j ; *j = temp ; ,指针变量能否作形参?,30,总结: 数组及指向数组的指针变量作函数参数时,可有种等价形式P238-239(本质上是一种,即指针数据作函数参数): (1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量,实参用数组名 (4)形参用数组名,实参用指针变量,31,10.3.4 指向多维数组的指针 多维数组元素的地址 int a34=1,3,5,7,9,11,13,15,17,19,21,23,a数组包括3个元素:a0 a1 a2,而每个元素又是一个一维数组。因此: a a0 第0行 printf( FORMAT , a , *a ) ; printf(FORMAT, a0 , *(a+0) ) ; printf(FORMAT, ,例10.10 输出二维数组有关的值,/* 第0行首地址,0行0列元素地址 */,/* 第0行0列元素地址 */,/* 第0行首地址,第0行0列元素地址 */,/* 第1行0列元素地址 ,第1行首地址 */,/* 第1行0列元素地址 */,/* 第2行0列元素地址 */,/* 第2行首地址 */,/* 第1行0列元素的值 */,36,2. 指向多维数组的指针变量 (1)指向数组元素的指针变量 例10.11 用指针变量输出数组元素的值。 main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p ; for( p=a0 ; p a0+12 ; p+ ) if ( p - a0 ) % 4 = 0) printf(“n”) ; printf(“%4d”, *p ); ,/* a0代表第0行0列元素地址 */,37,aij在数组(n*m)中的相对位置计算公式: i * m + j (m为数组的总列数) 如:a23 位置 = 2*4+3 (2)指向由m个元素组成的一唯数组的指针变量 例10.11的指针变量p是指向整型数据的,p+1表示指向下一个元素。可以使p不指向整型数据,而指向包含m个元素的一唯数组,这样p+1就表示下一行元素的首地址。,地址?, int (*p)4 , i , j ; p = a ; scanf( “ %d , %d ”, ,/*表示p所指的对象是有4个整型元素的数组,p只能指向一个包含4个元素的一唯数组*/,*p,*(p+1),输入:1,1 输出:11,更改后: 输入:1,1 输出:3,39,3.用指向数组的指针作函数参数 例 10.13 有一个班,3个学生,4门成绩。求所有成绩的平均分,第2个学生的各门成绩。,average(float *p ,int n) float *p_end; float sum=0,aver; p_end=p+n-1; for( ; p=p_end ; p+ ) sum=sum+(*p); aver=sum/n; printf(average=%5.2fn,aver); ,search(float (*p)4 , int n) int i; for( i=0 ; i4 ; i+ ) printf(%5.2f , *(*(p+n)+i) ;,main() float score34= 65,67,70,60,80,87,90,81,90,99,100,98; average( *score , 12); search( score , 2); ,/* 第0行0列元素地址 ,即 printf(“%s”,string); ,第4个元素表示: string4 = *(string+4) = v,41,(2) 用字符指针指向字符串 /*使用字符指针变量表示和引用字符串*/,char *string; string = “I love China!” ;,/* 把字符串的首地址赋给指针变量string,不是把字符串的值赋给string. */,*string = “I love China!”; 错,/*定义字符指针指向字符串*/,main() char *string = “I love China!” ; printf(“%s”, string ) ; ,42,例 10.17 把字符串a复制给字符串b,main() char a = “I am a boy.” , b20 ; int i ; for ( i=0 ; *(a+i) != 0 ; i+ ) * (b+i) = * (a+i) ; * (b+i) = 0 ; printf (“string a: %s ” , a ) ; printf (“string b: %s ” , b ) ; ,/*用指针法表示*/,main() char a = “I am a boy.” , b20 , *p , *q ; int i ; p = a ; q = b ; for ( ; *p != 0 ; p+, q+ ) * p = * q ; * q = 0 ; printf (“string a: %s n ” , a ) ; printf (“string b: %s ” , b ) ; ,本例能用指针变量处理吗?,43,10.4.2 字符指针作函数参数 当要调用子函数处理字符串时,需把字符串的地址从主调函数传送到子函数时,可以用字符数组名或指针作为函数的参数。 例10.10 用函数调用实现字符串的复制。 法:1) 用字符数组作参数,main( ) char a = “ I am a teacher. ” ; char b = “ you are a student. ” ; copy-string ( a , b ) ; printf(“string a=%s n string b=%s”, a , b ) ; ,void copy_string(char from ,char to ) int i=0; while ( from i != 0 ) to i = from i ; i+ ; to i =0 ; ,/*用字符数组名作实参*/,/*用字符数组作形参*/,44,注意: 由于b数组原来的长度大于a数组,因此将a数组复制到数组b后,未能全部覆盖b数组原有内容。b数组最后3个元素仍保留原状。在输出时由于按%s(字符串)输出,遇到0即告结束,因此第一个0后的字符不输出。如果采用%c逐个字符输出是可以输出后面这些字符的。,45,2) 用字符指针变量作形参,main( ) char from = “ I am a teacher. ” ; char to = “ you are a student. ” ; char * a = from , * b = to ; copy-string ( a , b ) ; printf(“string a=%s n string b=%s”, a , b ) ; ,void copy_string ( char *from , char *to ) for ( ; * from != 0 ; from+ , to+ ) * to = * from ; * to = 0 ; ,/*用字符指针作形参*/,/*用字符指针作实参*/,46,10.4.3 对使用字符数组和字符指针变量的讨论,(1)字符数组是由若干个元素组成,每个元素中放一个字符,而字符指针变量存放的是字符串第1个字符的地址(首地址),不是把字符串存到指针变量中; (2)赋值方式不同;,char * a ; a = “I love China!” ;,/*数组名是首地址,看作常量*/ 可以在定义时赋初值,不可以在语句中直接赋值,/*赋给a的是字符串的首地址,不是字符串本身*/ 也可以在定义时赋值,char str14 ; str = “I love China!” ;(错),char str = “I love China!” ;,47,(3)如果定义了一个字符数组,可以通过以下方式输入数据。,char str 10 ; scanf (“%s” , str ) ;,char *a ; scanf (“%s” , a ) ;,/*可行的*/,/*可行但危险的,因为定义a时只是分配了变量a的地址,并没有定义a的值(指向)。所以当程序规模大时,容易出现“冲突”,并且编译时会有警告提示*/,char *a ,str10 ; a = str ; scanf (“%s” , a ) ;,应改为:,48,(4)指针变量的值可以改变,例 10.20 改变指针变量的值,main( ) char *a = “I love China!” ; a = a+7 ; printf ( “%s” , a ) ; , char s = “I love China!” ; s = s+7 ; (错)/*数组名是常量,代表首地址*/ printf ( “%s” , s ) ;,main( ) char *a = “I love China!” ; printf ( “%c” , a5 ) ; /*用下标法引用指针变量*/,用下标法引用指针变量:,结果:China,/*改变了指针变量的值*/,49,(5)用指针变量指向一个格式字符串,用来代替printf函数中的格式字符串。 如: char *format = “a=%d , b=%fn” ; printf ( format , a , b ) ;,printf (“a=%d , b=%fn” , a , b ) ;,相当于,char format = “a=%d , b=%fn” ; printf ( format , a , b ) ;,也可用字符数组实现:,50,10.5 指向函数的指针 10.5.1 用函数指针变量调用函数 编译时,函数被分配给一个入口地址(即函数的指针),可以用一个指针变量指向函数,通过指针变量调用此函数。 回顾函数调用方法 例10.23 求a和b中的大者。,main( ) int max (int a,int b) ; int a , b , c ; scanf (“%d,%d”, ,再看:用函数指针变量访问函数,max ( int x , int y ) int z; if ( x y ) z = x ; else z = y ; return(z) ; ,等价于 c = max (a , b ) ;,51,说明: (1)指向函数的指针变量的定义形式: 数据类型 (*指针变量名)(函数参数列表); /* 数据类型是指函数返回值的类型 */ (2)函数的调用可以用函数名,也可以用函数指针; (3)指向函数的指针变量可以先后指向同一类型的不同函数; (4)给函数指针变量赋值时,只需给出函数名 如: p = max ; p = max (a,b) ;(错) (5)用指针变量调用函数时,只需用(*p)代替函数名; 如: c = ( *p ) (a,b) ; (6)指向函数的指针不能作 p+ 或 p+i 的操作。,/* 表示调用p指向的函数,实参为a,b,函数返回值的类型,由指针变量p的数据类型决定 */,52,10.5.2 用指向函数的指针作函数参数 函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量,另外函数的指针也可以作为函数的参数,即指向函数的指针变量作函数参数,是实现函数地址的传递 。 原理:假设, 函数sub(x1,x2)形参x1和x2为指向函数的指针变量; 调用函数sub时,假设实参为两个函数名f1和f2,传给形参的是函数f1和f2的入口地址; 这样,在函数sub中就可以调用函数f1和f2了。 用指针实现了函数的嵌套调用。,53,f1( ) f2( ) void sub ( int (*x1) (int) , int (*x2) (int , int) ) int a ,b , i , j ; a = (*x1) ( i ) ; b = (*x2) ( i , j ) ; main( ) sub ( f1 , f2 ) ; ,/* x1为形参,指向函数的指针变量,指向的函数只有一个参数 */,/* 相当于a=f1(i),调用f1函数 */,/* 实参为函数名,传递的是函数的入口地址 */,/* 相当于a=f2(i,j),调用f2函数 */,例如:,54,用指针变量可方便的调用不同函数,实现结构化程序设计。 例 10.23 用一个函数process,第一次调用它时找出a和b的大数,第二次调用找出小数,第三次调用找出总和。,int max ( int x , int y ) int z ; if ( xy ) z=x ; else z=y ; return (z) ; ,int min ( int x , int y ) int z ; if ( xy ) z=x ; else z=y ; return (z) ; ,int add ( int x , int y ) int z ; z = x+y ; return (z) ; ,void process ( int x , int y , int (*fun) ( int , int ) ) int result; result = ( *fun ) ( x , y ) ; printf ( “%dn” , result ) ; ,void main( ) int a , b ; scanf ( “%d,%d” , ,/*函数的入口地址*/,55,10.6 返回指针值的函数,一个函数可以返回一个int型、float型、char型的数据,也可以返回一个指针类型的数据。 返回指针值的函数(简称指针函数)的定义格式如下: 函数类型 *函数名(形参表) float search(float (*p)4,int n) float *tp; tp=*(p+n); return(tp); ,56,ccccc int *seek( int (*pnt_row)3 ) int i=0, *pnt_col; /*定义一个(列)指针变量pnt_col */ pnt_col=*(pnt_row+1); /*使pnt_col指向下一行之首(作标志 用)*/ for(; i3; i+) if(*(*pnt_row+i)60) /*某项成绩不合格*/ pnt_col=*pnt_row; /*使pnt_col指向本行之首*/ break; /*退出循环*/ return(pnt_col); ,57,/*主函数main()*/ main() int grade33=55,65,75,65,75,85,75,80,90; int i,j,*pointer; /*定义一个(列)指针变量pointer */ for(i=0; i3; i+) /*控制每个学生*/ pointer=seek(grade+i); /*用行指针作实参,调seek()函数*/ if(pointer=*(grade+i) /*该学生至少有一项成绩不合格*/ /*输出该学生的序号和各项成绩*/ printf(“No.%d grade list: ”, i+1); for(j=0; j3; j+) printf(“%d ”,*(pointer+j); printf(“n”); 程序运行结果: No.1 grade list: 55 65 75,58,程序说明: (1) 主函数中的pointer=seek(grade+i);语句 调用seek()函数时,将实参grade+i(行指针)的值,复制到形参pnt_row(行指针变量)中,使形参pnt_row指向grade数组的第i行。 (2)在指针函数seek()中: 1) pnt_col=*(pnt_row+1);语句 *(pnt_row+1)将行指针转换为列指针,指向grade数组的第i+1行第列,并赋值给(列)指针变量pnt_col。 2) if(*(*pnt_row+i)60)行 pnt_row是一个行指针,指向数组grade的第i行;*pnt_row使指针由行转换为列,指向数组grade的第i行列;*pnt_row+j的值还是一个指针,指向数组的第i行第j列;*(*pnt_rowj)是一个数据(数组元素gradeij的值)。,59,10.7 指针数组和指向指针的指针,10.7.1 指针数组的概念 一个数组,其元素均为指针类型数据,称为指针数组。数组的每个元素都是一个指针数据。指针数组比较适合用于指向多个字符串,使字符串处理更加方便、灵活。 定义格式: 数据类型 *数组名元素个数 例如: int *p4 由于 比*优先级高,因此P先与4结合,形成P4形式,然后再与P前面的“*”结合,“*”表示此数组是指针类型的,每个数组元素相当于一个指针变量,都可指向一个整型变量。 例 :有若干计算机图书,请按字母顺序,从小到大输出书名。解题要求:使用排序函数完成排序,在主函数中进行输入输出。/*程序功能:指针数组应用示例*/,60,void sort(char *name , int count) char *temp_p; int i,j,min; /*使用选择法排序*/ for(i=0; i0) /*存在更小的串*/ min=j; /*保存之*/ if(min!=i) /*存在更小的串,交换位置*/ temp_p=namei;namei=namemin; namemin=temp_p ; ,61,main() char*name5=“BASIC”,”FORTRAN”,”PASCAL ”,”C”,”FoxBASE”; int i=0; sort(name,5); /*使用字符指针数组名作实参,调用排序 函数sort()*/ for(;i5; i+) printf(“%sn”,namei); /*输出排序结果*/ 程序运行结果:BASIC C FORTRAN FoxBASE PASCAL,62,程序说明: (1)实参对形参的值传递: sort( name , 5 ); void sort(char *name, int count) (2)字符串的比较只能使用strcmp()函数。形参字符指针数组name的每个元素,都是一个指向字符串的指针,所以有strcmp(namemin,namej)。 主函数main()的形参 在以往的程序中,主函数main()都使用其无参形式。实际上,主函数main()也是可以指定形参的。 案例: 用同一程序实现文件的加密和解密。 约定:程序的可执行文件名为lock.exe, 其用法为:lock +|- ,其中“+”为加密,“-”为解密。,63,main(int argc, char *argv ) ccccc char c; if (argc != 3) printf(参数个数不对!n); else c=*argv1; /*截取第二个实参字符串的第一个字符*/ switch(c) case +: /*执行加密*/ printf(执行加密程序段。n); /*加密程序段*/ break; case -: /*执行解密*/ printf(执行解密程序段。n); /*解密程序段*/ break; default: printf(第二个参数错误!n); ,64,1.主函数main()的有参形式 main(int argc, char *argv) 2.实参的来源 运行带形参的主函数,必须在操作系统状态下,输入主函数所在的可执行文件名,以及所需的实参,然后回车即可。 命令行的一般格式为: 可执行文件名实参 实参2 本程序的用法:lock +|- 在TC的集成环境下,也可直接利用Options | Arguments 项,输入主函数所需要的实参:只须输入各参数(相邻参数间用空格分开),可执行文件名可省略。就本案例而言,输入“+|- ”即可。,65,3.形参说明 (1)形参argc是命令行中参数的个数(可执行文件名本身也算一个)。 在本案例中,形参argc的值为3(lock、+|-、文件名)。 (2)形参argv是一个字符指针数组,即形参argv首先是一个数组(元素个数为形参argc的值),其元素值都是指向实参字符串的指针。 在本案例中,元素argv0指向第1个实参字符串“lock”,元素argv1 指向第2个实参字符串“+|-”,元素argv2指向第3个实参字符串“被处理的文件名”。,66,10.7.2 指向指针的指针 指向指针数据的指针变量,简称为指向指针的指针。 怎样定义一个指向指针数据的指针变量呢? 形式: char * *p; 相当于*(*p),显然*P是指针变量的定义形式。现在又加一个*号,表示指针变量P是指向一个字符指针变量的。*P就是P所指向的另一个指针变量。,67,例10.28指向指针的指针的应用 main() char *name=“f0llowme”,”basic”,great wall”,”fortran”,computer design”); char *p; int i; for(i=0;i5;i+) p=name+I; printf(“%sn”,*p); ,68,指向指针的指针变量简介 在案例的主函数main()中,数组name是一个字符指针数组,即数组的每一个元素都是一个指向字符串的指针。 既然name是一个数组,则它的每一个元素也同样有相应的地址,因此可以设置一个指针变量pointer,使其指向指针数组的元素(元素的值还是一个指针),称pointer为指向指针的指针变量。显然,指向指针的指针变量是一个两级的指针变量。 1.指向指针的指针变量的定义 数据类型 *指针变量, *指针变量2; 2.指向指针的指针变量的赋值 指针变量 = 指针数组名 + i,69,例如10.29 指针数组的元素指向数据 main() static int a5=(1,3,5,7,9; int *num5= 输出结果:,70,10.8 有关指针的数据类型和指针的小结 10.8.1 有关指针的数据类型的小结 int i 定义整型变量i int *p; P为指向整型数据的指针变量 int an; 整型数组a有n个元素 int *pn; P由n个指向数据的指针元素组成 int(*p)n; P为指向n个元素的数组的指针变量 int f( ); f为带回整型函数值的函数 int *p( ); P为带回一个指针的函数,该指针 指向整数 int(*p)( ); P为指向函数的指针,返回一个整型值 int * *p; p指针变量指向整型数据的指针变量,71,二 10.8.2 指针运算小结 1)指针变量加、减:P+ P- - P+i P-i P+=i P-=等 2)指针变量赋值:P= void *p2; p1=(char *)p2; void *指针类型是ANSI系统新加的,若详细了解可参阅有关手册。,73,有以下程序 #include main() int m=1,n=2,*p= 程序运行后的输出结果是B A)1,2,1,2 B)1,2,2,1 C)2,1,2,1 D)2,1,1,2,74,有以下程序 #include #include main( ) char str 20=“One*World”, “One*Dream!”, *p = str1 ; printf(“%d,”, strlen(p) ) ; printf(“%sn” , p ) ; 程序运行后的输出结果是C A)9,One*World B)9,One*Dream C)10,One*Dream! D)10,One*World,/*p指向了第1行0列元素的地址*/,75,下列函数的功能是A fun( char *a , char *b ) while( (*b = *a) != 0 ) a+ , b+; A)将a所指字符串赋给b所指空间 B)使指针b指向a所指字符串 C)将a所指字符串和b所指字符串进行比较 D)检查a和b所指字符串中是否有0,76,若有定义语句: int a410 , *p , (*q)4 ;且0i4,则错误的赋值是B /* q是指向一维数组的指针 */ A)p = a B)qi = ai C)p = ai D)p = printf(“%d,%dn”, strlen(a) , sizeof(a) ); 程序运行后的输出结果是B A)7,4 B)4,10 C)8,8 D)10,10,strlen(a)测定a中不包括0字符个数; sizeof(a)测定a所占的字节数。,78,设有以下函数 void fun( int n , char * s ) 则下面对函数指针的定义和赋值均是正确的是A A)void (*pf)( ) ; pf = fun ; B)viod *pf( ) ; pf = fun ; C)void *pf( ) ; *pf = fun ; D)void (*pf)(int,char) ; pf = ,79,设有定义:char *c;,以下选项中能够使字符型指针c正确指向一个字符串的是A A)char str = ”string” ; c = str ; B)scanf(“%s”,c); C)c = getchar() ; D)*c = ”string” ;,80,int f(int n); main() int a = 3 , s ; s = f(a) ; s = s+f(a) ; printf(“%dn”,s) ; int f(int n) static int a=1; n += a+ ; return n; 程序运行以后的输出结果是C A)7 B)8 C)9 D)10,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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