c++课件第六章指针_第1页
c++课件第六章指针_第2页
c++课件第六章指针_第3页
c++课件第六章指针_第4页
c++课件第六章指针_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 第六章 指 针6.1 指针的概念内存区的每一个字节有一个编号,这就是“地址”。&是取地址运算符,&i是变量i的地址。一个变量的地址称为该变量的指针。如果一个变量是专门存放另一个变量的地址,则称它为指针变量。6.2 变量与指针6.2.1 定义指针变量int i,j;int *pi=&i,*pj; /pi,pj是指向整型数据的指针变量。double *pd;pj=&j;一般的C+编译系统为每一个指针变量分配4个字节的存储单元。6.2.2 引用指针变量(1)& 取地址运算符号(2)* 指针运算符(或称间接引用运算符)*p为指针变量p所指向的存储单元。#include void main()int

2、var=8;int* pointer;pointer=&var;*pointer=5;coutvar *pointer *(&var)endl;coutpointer &pointer &var &(*pointer)endl;5 5 50x0064FDF0 0x0064FDF4 0x0064FDF0 0x0064FDF0例6.1 通过指针变量访问整型变量#include using namespace std;void main()int a,b;int *p1,*p2;a=100;b=10;p1=&a;p2=&b;couta bendl;cout*p1 *p2endl;100 10100

3、10&*p1,*&a的含义是什么?例6.2 输入a和b两个整数,按先大后小的顺序输出(用指针变量处理)#include using namespace std;void main()int *p1,*p2,*p,a,b;cinab;p1=&a;p2=&b;if(ab)p=p1;p1=p2;p2=p;couta=a b=bendl;coutmax=*p1 min=*p2endl;45 78a=45 b=78max=78 min=45调用函数时不会改变实参指针变量的值,但可以改变实参指针变量所指向变量的值。6.2.3 指针作为函数参数例6.3 题目同例6.2#include using names

4、pace std;void main()void s *p1,int *p2);int *pointer_1,*pointer_2,a,b;cinab;if(ab)s, &b);coutmax=a min=bendl;void s *p1,int *p2)int temp;temp=*p1;*p1=*p2;*p2=temp;45 78max=78 min=45例6.4 输入a,b,c三个整数,按由大到小的顺序输出。#include using namespace std;void main()void exchange(int *,int *,int *);int a,b,c,*p1,*p2,

5、*p3;cinabc;p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);couta b cendl;void exchange(int *q1,int *q2,int *q3)void s *p1,int *p2);if(*q1*q2)s);/前两个if选出最大,if(*q1*q3)s);/放入q1所指的变量中if(*q2*q3)s);void s *p1,int *p2)int temp;temp=*p1;*p1=*p2;*p2=temp;12 -56 8787 12 -566.3 指针与数组6.3.1 指向数组元素的指针在中,一个数组类型的操作数被自动转换为指向数组

6、第一个元素的常量指针。int a10;int *p;p=&a0; 与语句 p=a; 等价。int *q=a;*q=5;如果p的初值&a0,则:(1) p+i和a+i就是ai的地址。(2) *(p+i)和*(a+i)就是ai。(3) pi和*(p+i)等价。(下标法和指针法)int a10;coutaendl;couta+1endl;couta+2endl;能够发现地址值差4#includevoid main()int a10=2,4,6,8,10;for(int* p=a;pa+10;p+)coutp0 ; /等价于cout*p;coutendl;coutp-6 ;coutp-7 ;coutp

7、-8 ;coutp-9 ;coutp-10endl;2 4 6 8 10 0 0 0 0 010 8 6 4 2和*优先级相同,结合规则是自右至左,即自右向左运算,下面是对应的结果:y=*px+; /等价于y=*(px+);y=*+px /等价于y=*(+px);y=+*px / 等价于y=+(*px);y=(*px)+;由于后缀运算的特点,第一个表达式将px指向的变量的值赋给y,然后使px指向下一个变量。第二个表达式将px指向下一个变量,然后再将px指向的变量的值赋给y。后两个表达式对px的指向的变量进行增1运算,px未被改变。#includevoid main()int a10=2,4,6

8、,8,10,12,14,16,18;int y;int* px=a;y=*px+; /等价于y=*(px+);couty *pxendl;/此时px指向a+1 y=2 *px=4y=*+px; /等价于y=*(+px);couty *px pxendl;/此时px指向a+2 *px=6 y=6couta2endl;y=+*px; / 等价于y=+(*px);couty *px pxendl; /此时px指向a+2未变,a2的值是6+1couta2endl;y=(*px)+;couty *pxendl; /此时px指向a+2未变,a2的值是6+1+1couta2endl;2 46 6 0x006

9、4FDD867 7 0x0064FDD877 88(1)*(p+)与*(+p)作用不同。前者是先取*p值,然后使p加1。后者是先使p加1,再取*p。(2)(*p)+表示p所指向的元素值加1。(3)如果p当前指向ai,则*(p-) 先对p进行”*”运算,得到ai,再使p减1,p指向ai-1.*(+p) 先使p自加1,再作*运算,得到ai+1。*(-p) 先使p自减1,再作*运算,得到ai-1。6.3.2 用指针变量作函数参数接收数组地址例6.6 将10个整数用选择排序按由小到大的顺序排列。#include using namespace std;void main()/void select_s

10、ort(int array,int n);void select_sort(int *p,int n);int a10,i;coutenter the original array:endl;for(i=0;iai;select_sort(a,10);coutthe sorted array:endl;for(i=0;i10;i+) coutai ;coutendl;void select_sort(int *p,int n)int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(*(p+j)*(p+k)k=j;t=*(p+k);*(p+k)=*(

11、p+i);*(p+i)=t;/*void select_sort(int array,int n)int i,j,k,t;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(arrayjarrayk)k=j;t=arrayk;arrayk=arrayi;arrayi=t;*/enter the original array:6 9 -2 56 87 11 -54 3 0 77the sorted array:-54 -2 0 3 6 9 11 56 77 87例 使用函数input 输入一组数,然后由main显示出该组数的例子。#includevoid main()i

12、nt a10;void input(int *s,int n );input(a,10);for (int i=0;i10;i+)coutai ;coutendl;void input(int *s,int n) cout Please enter n integersendl; for(int i=0;isi;Please enter 10 integers1 2 3 4 5 6 7 8 9 101 2 3 4 5 6 7 8 9 10#include void fun(int *a,int *b)int k;cout*a *bendl;k=*a;*a=*b;*b=k;void main()

13、int a=3,b=6,*x=&a,*y=&b;couta bendl;fun(x,y);couta bendl;3 63 66 36.3.3 多维数组与指针1. 多维数组元素的地址int a34=1,3,5,7,9,11,13,15,17,19,21,23;a是一个数组名。a数组包含3行,即三个元素:a0,a1,a2。而每一元素又是一维数组,它包含4个元素。#include using namespace std;void main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;couta &a00endl;couta+1 &a10endl;couta+2

14、&a20endl;cout*(a1+1) *(*(a+1)+1) a11endl;0068FDC8 0068FDC80068FDD8 0068FDD80068FDE8 0068FDE811 11 112. 指向多维数组元素的指针变量(1) 指向数组元素的指针变量例6.7 输出二维数组各元素的值#include using namespace std;void main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int *p;/for(p=a0;p*a+12;p+)for(p=a0;pa0+12;p+)cout*p ;coutendl;1 3 5 7 9 1

15、1 13 15 17 19 21 23(2) 指向由m个元素组成的一维数组的指针(指向数组的指针)#includevoid main() int n35=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;int (*a)5=n;for(int i=0;i5;i+)cout(*a)i ;coutendl;for(i=0;i5;i+)cout(*(a+1)i ;coutendl;for(i=0;i5;i+)cout(*(a+2)i ;coutendl;1 2 3 4 56 7 8 9 1011 12 13 14 15#includevoid main() int n35=1,

16、2,3,4,5,6,7,8,9,10;int (*a)5=n;int *p;cout*a nendl;/ 0x0064FDB0 0x0064FDB0p = *a;a+=1;/使a指向下一个int5 这两句可用 p=*a+;代替。cout*a pendl;/前后两个a差20,说明a是指向int5的指针。0x0064FDC4 0x0064FDB0for(int i=0;i5;i+)cout*p+ ;/1 2 3 4 5coutendl;p = *a;cout*a pendl;/ 0x0064FDC4 0x0064FDC4for(i=0;i5;i+)cout*p+ ;/6 7 8 9 10coute

17、ndl;cout*aendl;/ 60x0064FDB0 0x0064FDB00x0064FDC4 0x0064FDB01 2 3 4 50x0064FDC4 0x0064FDC46 7 8 9 106#include using namespace std;void main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int (*p)4,i;for(p=a;pa+3;p+)for(i=0;i4;i+)cout*(*p+i) ;/coutp0i ;/cout(*p)i ;coutendl;1 3 5 7 9 11 13 15 17 19 21 233. 用

18、指向数组的指针作函数参数例6.9 输出二维数组各元素的值#include using namespace std;void main()void output(int(*p)4);int a34=1,3,5,7,9,11,13,15,17,19,21,23;output(a);void output(int (*p)4)int i,j;for(i=0;i3;i+)for(j=0;j4;j+)cout*(*(p+i)+j) ;coutendl;1 3 5 7 9 11 13 15 17 19 21 23#include void main()int a45;void input(int s5,i

19、nt n);input(a,4);for(int i =0;i4;i+)for(int j=0;j5;j+)coutaij ;coutendl;void input(int s5,int len)coutPlease enter a len rows by 5 columns matrix:endl;for(int i=0;ilen;i+)for(int j=0;jsij;cin(*(s+i)j;Please enter a 4 rows by 5 columns matrix:1 2 3 4 510 20 30 40 5011 22 33 44 55100 200 300 400 5001

20、2 3 4 510 20 30 40 5011 22 33 44 55100 200 300 400 5006.4 字符串与指针1.用字符数组存放一个字符串例6.10#include void main()char str=I love CHINA!; 0coutstrendl;I love CHINA!2. 用字符串变量存放字符串例6.11#include #include using namespace std;void main()string str=I love CHINA!;coutstrendl;I love CHINA!4. 用字符指针指向一个字符串例6.12#include

21、using namespace std;void main()char *str=I love CHINA!;coutstrendl;I love CHINA!例6.13 将字符串str1复制为字符串str2#include using namespace std;void main()char str1=I love CHINA!;char str220,*p1,*p2;p1=str1;p2=str2;for(;*p1!=0;p1+,p2+)*p2=*p1;*p2=0;coutstr1 is str1endl;coutstr2 is str2endl;str1 is I love CHINA

22、!str2 is I love CHINA!字符串常量的类型是char,在内存开辟了一个字符数组用来存储该字符串常量。一个字符串常量可以作为操作数来初始化一个字符指针,例如: char * ps =”string”;这时,变量ps中保存的是串”string”的第一个元素的地址,在程序中,也可以直接把一个字符串常量赋给一个字符指针,例如: char * ps; ps = “string”;在赋值过程中,并不是把字符串复制到指针中,而是将存储字符串的内存的首地址赋给指针,所以指针ps指向字符串的首字符s。下面的程序用于演示上面介绍的内容。#include void main()char str=P

23、rogram;char *ps;ps=str;while (*ps!=0)cout*ps+ ;coutendl;ps=hello;while (*ps)cout*ps+ ;coutendl;coutstrendl;coutpsendl;coutps-2endl;P r o g r a mh e l l oProgramlo当字符0被用作操作数时,它被转换成0。即 0和0值相等,但前者的类型为char,而后者的类型为int.所以语句 while( * ps!= 0)可以写成 while( * ps)字符串的长度:#includeint strlen(const char *s)/返回字符串s的长

24、度int len=0;while(*s+)len+;return len;void main()char buf80;coutbuf;coutThe length of string buf is strlen(buf)endl;Enter a word:abcdeThe length of string abcde is 5字符串的拷贝和连接:#includechar * strcpy(char *dest,const char *src)/字符串拷贝char *temp = dest;while(*dest+=*src+) /dest 和 src 的指针虽然改变; /但不影响主程序的指针值

25、return temp;char * strcat(char *dest,const char *src)/字符串连接char *temp = dest;while(*dest+);dest-;while(*dest+=*src+);return temp;void main()char first40,second40,third40;char result80;coutfirst;coutsecond;coutthird;coutstrcpy(result,first);coutendl;coutstrcat(result,second);coutendl;coutstrcat(resul

26、t,third);coutendl;coutresultendl;Enter first word:1111Enter second word:2222Enter third word:33331111111122223333111122223333注意:如果忘记为整个目标串(包括null字符)在缓冲区中分配足够内存,strcat和strcpy函数可能有害于程序,它可能越界删除其它数据,可使程序失败。字符串比较:#includeint strcmp(const char *s1,const char *s2)/字符串比较/返回值 0 s1大于s2 for(;*s1=*s2;s1+,s2+)if

27、(!*s1)return 0;return *s1-*s2;void main()char first40,second40;coutfirst;coutsecond;coutstrcmp(first,second)endl;Enter first word:abcdeEnter second word:abfde-3系统在头文件string.h中说明了许多用于对串进行处理的函数,可以使用系统函数strlen得到一个串的长度。函数strlen使用一个串作为它的形参返回unsigned类型的值。但串的长度不包括字符 0,使用函数strlen和使用运算符sizeof时得到的结果相差1。系统函数提供

28、了许多字符串操作,例如strcpy用于将一个串拷贝到另一个串中,函数strcat用于连接两个串,函数strcmp用于比较两个串等等。字符指针的空间使用第一种:使用字符数组的空间#include#includemain()char *s1;char s28=ABCDEFG;s1=s2;/将地址s2赋给地址s1*s1=H;/对s1的修改就是对s2修改couts1=s1 s2=s2endl;s1=HBCDEFG s2=HBCDEFG第二种:使用字符串常量#include#includemain()char *s1;char s28=ABCDEFG;s1=sadjfsaldkfjsdafjsdasdf

29、j;strcpy(s1,s2);/将地址s2所指向的字符串复制到地址s1所指向的字符串*s1=K;couts1=s1 s2=s2endl;s1=KBCDEFG s2=ABCDEFG第三种:使用new和delete#include#includemain()char *s1;char s28=ABCDEFG;s1=new char8;strcpy(s1,s2);/将地址s2所指向的字符串复制到地址s1所指向的字符串*s1=K;couts1=s1 s2=s2endl;delete s1;s1=KBCDEFG s2=ABCDEFG对字符指针和字符数组的赋值的方法第一种按单个字符的方法#include

30、#includemain()char *s1;char s28=ABCDEFG;s1=new char8;*s1=F;*(s1+1)=S;*(s1+2)=T;*(s1+3)=0;couts1endl;delete s1;s21=8;couts2endl;FSTA8CDEFG第二种使用strcpy和strcat函数的方法和字符指针的字符串常量的方法#include#includemain()char *s1;char s28=ABCDEFG;/s2=BBBAAA;/错误 s2是地址常量,不能再进行赋值操作/s2=s1;/错误/strcpy(s1,s2);/错误,没有为s1分配内存空间。/strc

31、py(s2,1234567890123456789);/错误 地址越界s1=0123456;strcpy(s1,s2);couts1endl;strcpy(s2,tow);strcat(s2,ijk);couts2endl;ABCDEFGtowijk6.5 函数与指针6.5.1 用函数指针变量调用函数下面一个函数原型的说明: int fun(int a,int b);指向函数的指针说明如下: int(*funp)(int a,int b);#includeint fun(int a,int b);int fun1(int a,int b);void main()int x=8,y=5;int(

32、*funp)(int a,int b);funp=fun;coutfunp(x,y)endl;coutfun funpendl;funp=fun1;coutfunp(x,y)endl;coutfun1 funpendl;int fun(int a,int b)return a+b;int fun1(int a,int b)return a-b;130x00401023 0x0040102330x00401014 0x004010146.6 返回指针值的函数例 使用函数input输入一组数并返回一个指针,然后由main将这组数显示出来的例子.#includevoid main()int num;

33、float * data;float * input(int *n);data = input(&num);if(data)for(int i=0;inum;i+)coutdatai ;coutendl;delete data; coutnumendl;float * input(int *n)cout*n;if(*n=0)return 0;float *buf =new float*n;if(buf=0)return 0;cout输入*n个浮点数:;for(int i=0;ibufi;return buf;Input number:2输入2个浮点数:1.1 2.21.1 2.22注意:使用i

34、nput函数的函数应负责释放由input函数分配的内存。如果需要上面的函数接收用户输入一个方阵所需的数据,方阵的大小为n * 5,n由用户输入的值输入的值确定。可以定义为: float(*input(int *n)5;则有 float(*buf)5=new floatnum5;这个函数返回一个指向数组的指针。#includevoid main()int num;float (*data)5;float(*input(int *n)5;data = input(&num);if(data)for(int i=0;inum;i+)for(int j=0;j5;j+)coutdataij ;cout

35、endl;delete data; coutnumendl;float(*input(int *n)5cout*n;if(*n=0)return 0;float(*buf)5=new float*n5;if(buf=0)return 0;cout输入*n行,每行5个浮点数:endl;for(int i=0;i*n;i+)for(int j=0;jbufij;return buf;Input number:2输入2行,每行5个浮点数:1.1 2.2 3.3 4.4 5.51 2 3 4 51.1 2.2 3.3 4.4 5.51 2 3 4 52一个函数不能返回一个自动变量的地址,例如:int

36、* fun() int a10;/.return a; void main()int * p;p=fun();6.7 指针数组和指向指针的指针如果一个数组,其元素均为指针类型的数据,该数组称为指针数组.类型名 *数组名数组长度int* pa2;在解释变量说明语句中变量的类型时,说明符的优先级高于*,即先解释,再解释*,所以,pa的类型被表示为 pa2*int即pa是有两个元素的数组,每个元素是个指向int类型的指针。下面的程序说明指针数组的使用:#includevoid main() int a23=2,4,6,8,10,12;int* pa2;pa0=a0;pa1=a1;for(int i=

37、0; i2; i+)for(int j=0;j3;j+)cout aij=*(pai+j) ;/cout aij=paij ;a00=2 a01=4 a02=6 a10=8 a11=10 a12=12例6.15 若干字符串按字母顺序(由小到大)输出#includeusing namespace std;void main()void sort(char *name,int n);void print(char *name,int n);char *name=BASIC,FORTRAN,C+,Pascal,COBOL;int n=5;sort(name,n);print(name,n);void

38、 sort(char *name,int n)char *temp;int i,j,k;for(i=0;in-1;i+)k=i;for(j=i+1;j0)k=j;if(k!=i)temp=namei;namei=namek;namek=temp;void print(char *name,int n)int i;for(i=0;in;i+)coutnameiendl;BASICC+COBOLFORTRANPascal6.7.2 指向指针的指针char *p;/自右至左例6.16 指向字符型数据的指针变量#includeusing namespace std;void main()char *p

39、;char *name=BASIC,FORTRAN,C+,Pascal,COBOL;p=name+2;cout*pendl;cout*pendl;C+C6.9 引用包含一种与指针有关的特性,这一特性称为引用。引用产生另一变量的别名,因而可以通过引用来传递参数给函数。6.9.1 什么是变量的引用引用说明:引用运算符&用于定义一个引用。如果这个引用不是用函数的参数或返回值,则在说明时必须进行初始化。例如: int num=50; /这个变量必须赋值 int &ref=num;ref被说明为引用一个整型的变量,所以使用int类型的变量num给其置初始值,我们称int为ref的引用类型。下面程序说明引

40、用的使用。6.9.2 引用的简单使用#includevoid main()int num=500;int& ref =num;ref =ref+100;cout “num=”numendl;num=num+50;cout “ref=”refendl;引用不是变量,在程序中对引用的存取都是对它所引用的变量的存取,引用实质上是为另一个变量建立别名。上述程序的输出是: num=600; ref=650;可以说明对指针的引用。例如:int *a;int *&p=a;int b;p=&b ; /a 指向变量b实现程序如下:#includevoid main()int *a;int c=8;a=&c;co

41、ut*aendl;/输出8int *&p=a;cout*pendl; /输出8int b;b=9;p = &b ; /a 指向变量bcout*aendl; /输出9889当使用&运算符取一个引用的地址时,其值为所引用的变量的地址,例如:#includevoid main()int num=50;int& ref=num;int* p =&ref;/用引用给指针赋值coutp &num &refendl;则p 中保存的变量num的地址。可以用一个引用初使化另一个引用,例如#includevoid main()int num=50;int& ref1=num;int& ref2=ref1;ref2

42、=100; /num被修改为100coutnumendl;其中ref2也是对num的引用。下面的程序使用引用所建立的变量的一个名字(用引用为用new建立的变量命名):#includevoid main()int& ref =* new int(10);coutrefendl;ref=15;coutrefendl;delete &ref ;其中ref是为new所建立的变量的名字,&ref是该变量的地址,所以将它用作delete 操作符来删除该变量。6.9.3 引用作为函数参数例6.18 要求将变量i和j的值互换。下面的程序无法实现此要求。#includevoid main()void s);in

43、t i=3,j=5;s);couti=i,j=jendl;void s a,int b)int temp=a;a=b;b=temp; i=3,j=5(1) 传值:将变量名作为实参和形参,这时传给形参的是变量的值,传递是单向的。(2) 传地址:形参是指针变量,实参是变量的地址,调用函数时,形参(指针变量)指向实参变量单元。例6.19 使用指针变量作形参,实现两个变量的值的互换。#includevoid main()void s *,int *);int i=3,j=5;s);couti=i,j=jendl;void s *p1,int *p2)int temp=*p1;*p1=*p2;*p2=t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论