1、第6章 指 针,61 变量的地址和指针变量的概念 62 指针变量的定义和引用 63 指针和一维数组 64 指针和字符串实例的部分程序,6.1 变量的地址 和指针变量的概念,3,6,7,8,15,16,A公司,B公司,C公司,一排平房,叫地址,1000,int a;,float b;,内存管理,1001,2002,2003,2000,2001,a的地址,b的地址,说明:,变量a的地址记作&a 指针变量专门存放另一变量的地址,62 指针变量的定义和引用,【例61】指针变量的定义和引用示例,int a;,int *p;,p=,*p=5;,printf(“%d“,a);,a,p,&a,*p,5,输出
2、5,p中只能存放整型变量的地址,请思考:,int a;,int *p;,p=,*p=5;,a,p,5,若已有:int *w;,w,要使w也指向a,应如何操作?,w=,或w=p;,请思考:,int a;,int *p;,w=p=,*p=5;,a,p,5,int *w;,w,要使a的值增1,应如何操作?,a=a+1;,或*p=*p+1;,或*w=*w+1;,int a;,int *p;,w=p=,*p=5;,a,p,5,int *w;,w,a=a+1;,或*p=*p+1;,或*w=*w+1;,等价于int *p,*w;,间接运算符,取地址运算符,直接存取,间接存取,【例62】给指针变量赋值示例,m
3、ain( ) float a,b=6.0,*p,*q;p= ,6.0,a,b,q,p,float a,b=6.0,*p,*q;,p=,*p,scanf(“%f“,p);,1.0,1.0,*p=*p+2;,3.0,q=p;,*q,p=,*p,printf(“%f,%f“,*q,*p);,输出:3.000000,6.000000,【例63】非法使用指针示例。 #include main( ) int *p,a=1; float *q;*p=5; q= , p没有确定的指向, q只能指向float型变量,输出:125,5,0,-NAN,P=NULL;,显示错误信息,空指针,【例64】用指针变量的引用
4、方法编写程序。输入三个整数,输出其中最大数(算法参见例36)。,#include main( ) int a,b,c,max, *p, *q, *w, *m;p= ,p,a,q,b,w,c,m,max,*p,*q,*w,*m,63 指针和一维数组,631 使指针变量指向一维数组 632 对指针的算术运算,一维数组占连续的存储单元 称第一个元素的地址为数组的地址 用数组名表示首地址,6.3.1 使指针变量指向一维数组,【例65】使指针变量指向一维数组或数组元素的示例,a,p,b,q,0 1 2 3 4,p=,或p=a;,q=,或q=b+2;,for ( i=0; i5; i+ ),ai=i;,或
5、*(p+i)=i;,printf(“%4d“, ai);,或*(a+i),输出 0 1 2 3 4,a,p,b,q,0 1 2 3 4,7.0 6.0 5.0,p=a;,或p=,q=,或q=b+2;,for ( i=0; i5; i+ ),*(p+i)=i;,或ai=i;,printf(“%4d“,*(a+i);,或ai,输出 0 1 2 3 4,printf(“n“);,*q = 5; *(q-1) = 6; *(q-2) = 7;,printf(“%4.1f%4.1f%4.1fn“,b0, b1, b2);,输出 7.0 6.0 5.0,a,p,0 1 2 3 4,请思考:,若a0的地址为
6、1000, 则a1、a2、a3、a4的地址?,1002、1004、1006、1008,a,p,0 1 2 3 4,请思考:,当p指向a 时, a1、a2、a3 、 a4的地址如何表示?,元素 a1、a2、a3 、 a4如何表示?,a+1 、 a+2 、 a+3 、 a+4,p+1 、 p+2 、 p+3 、 p+4,其它?,*( ),*( ),*( ),*( ),*( ),*( ),*( ),*( ),pi可取代*(p+i),p与a的变化规律相同,a,0 1 2 3 4,请思考:,当p指向a4 时, a0 、 a1、a2、a3 的地址如何表示?,元素 a0 、 a1、a2、a3 如何表示?,a
7、 、 a +1 、 a+2 、 a+3,p-4 、 p-3 、 p-2 、 p-1,*( ),*,*( ),*( ),*( ),*( ),*( ),*( ),p与a的变化规律不同,说明: 指针指向连续存储单元时,能进行加或减一个整数的运算 保证运算后的地址值不超出原连续存储单元的地址范围,p+2、q-2 是合法运算 p+5、q-3 是不合法运算,632 对指针的算术运算,(1)int a5,*p=a;float b3,*q=,2个存储单元字节数,632 对指针的算术运算,q-p的结果为9,(2)当两个指针指向同一个连续存储单元时,对这两个指针可以进行相减的运算,(2)当两个指针指向同一个连续存
8、储单元时,对这两个指针可以进行相减的运算,632 对指针的算术运算,q-p的结果为?,3,(2)当两个指针指向同一个连续存储单元时,对这两个指针可以进行相减的运算,632 对指针的算术运算,q-p的结果为?,-5,【例66】移动指针和比较指针的示例。,int a10;,int *p=a;,int *q=,a,p,q,p=p+8;,输出:q不大于p,printf(“%dn“, q - p);,-5,printf(“q不大于pn“);,移动指针时应避免超范围,【例67】有10个元素的数组,完成以下功能:,(1)按顺序输出数组中的值,int i, a10=1,2,3,4,5,6,7,8,9,10,*
9、p=a; for( i=0; i10; i+ ) printf(“%4d“,*(p+i); printf(“n“);,指针没移动,(2)按逆序重新存放后输出(定义t),while ( pq ) t=*p; *p = *q; *q = t; p+; q-; ,t=*p; *p = *q; *q = t;,p+; q-;, ,pq,t=*p; *p = *q; *q = t;,p+; q-;,for( p=a; p-a10; p+ ) printf(“%4d“,*p);,(2)按逆序重新存放后输出(定义变量t),p,q,*p,p,*p,*p, ,a,p=a,printf(“%4d“,*p);,10
10、,9,8,7 6 5 4 3 2 1,【例68】假设数组中存放互不相同的10个整数,要求输入一个整数,查找与该值相同的数组元素,如果存在,输出其下标值,否则,输出相应信息(参见例59)。,main( ) int k,*p,a10=1,2,3,4,5,6,7,8,9,10;printf(“Input k:“); scanf(“%d“,printf(“n“); for( p=a; p-a 10; p+ )if ( k = *p ) break;,*p,k = *p,if( p-a 10 ) printf(“下标值=%dn“, p-a); else printf(“没找到 %dn“,k); ,p-a
11、 10,正常退出,提前退出,p-a?,main( ) int k,*p,a10=1,2,3,4,5,6,7,8,9,10;printf(“Input k:“); scanf(“%d“,printf(“n“); for( p=a; p-a 10; p+ )if ( k = *p ) break;,*p,k = *p,if( p-a 10 ) printf(“下标值=%dn“, p-a); else printf(“没找到 %dn“,k); ,p-a 10,请思考:,a,p,3,【例69】在数组中找出最大元素,并与第一个元素对调(算法参见例511),第一步:求最大值所在元素下标,q=a; for(
12、 p=a+1; p-a10; p+ )if ( *q *p ) q = p;,第二步:最大元素与第一个元素对调,8,10,a,q,p,temp=a0; a0=*q; *q=temp;,#include main( ) int temp, *p, *q, a10= 8,9,1,2,5,10,7,3,4,6; for ( p=a; p-a10; p+ ) printf(“%4d“,*p); printf(“n“);,temp=a0; a0=*q; *q=temp;,for ( p=a; p-a10; p+ ) printf(“%4d“,*p); ,q=a; for( p=a+1; p-a10; p
13、+ )if ( *q *p ) q = p;,64 指针和字符串,641 通过字符数组名引用字符串 642 通过指针变量引用字符串,6.4.1 通过字符数组名引用字符串,【例610】通过字符数组名引用字符串示例。,#include #include main( ) int i;char a8=“First“;puts(a); strcpy(a,“Second“); for( i=0; *(a+i) != 0 ; i+ ) putchar(*(a+i); ,for( i=0; *(a+i) != 0 ; i+ ) putchar(*(a+i);, printf(“%sn“,a);,a=“Seco
14、nd“; ,等价于ai,First,Second,char a8=“First“;,puts(a);,strcpy(a,“Second“);,6.4.2 通过指针变量引用字符串,【例611】通过指针变量引用字符串示例。,#include main( ) char *p=“First“;puts(p); p=“Second“; for( ; *p != 0 ; p+ )putchar(*p); ,p,char *p=“First“;,puts(p);,p=“Second“;,First,Second,for( ; *p != 0 ; p+ )putchar(*p);,【例612】编写求字符串长度
15、的程序(参见例520_2),#include main( ) ,gets(p);,I am OK,puts(p);,I am OK,p,char a80, *p; p=a;,while( *p != 0 ) p+;,printf( “长度=%dn“,p-a );,长度=7,I a m O K 0,【例613】编写字符串复制的程序,a,b, ,while( *p != 0 ) *q = *p; p+; q+; ,*q = 0;,p,q,【例613】编写字符串复制的程序,p,q,#include main( ) char a50,b80, *p, *q;p=a; q=b; printf(“Inpu
16、t data: “); gets(a); while( *p != 0 ) *q = *p; p+; q+; *q = 0; puts(b); ,【例614】编写字符串连接的程序(参见例522_2),while( *p != 0 ) p+; while( *q != 0 ) *p = *q; p+; q+; *p = 0;,【例615】编写字符串比较的程序(参见例523_2),while( *p = *q ,实例的部分程序,【实例6】编写查询所需记录的程序 【实例7】编写修改通讯记录的程序 【实例8】编写添加通讯记录的程序 【实例9】编写删除通讯记录的程序 【实例10】编写排序通讯记录的程序 演示shili_6.exe shili_7.exe shili_8.exe shili_9.exe shili_10.exe,