1 / 34

本章主要内容

指针. 本章主要内容. 指针的含义 指针使用 不同类型指针的区别 指针与数组的关系 动态单元分配 复杂指针 ( 选学 ) 二维数组的地址 指针数组 指针的指针 数组指针. 指针的含义. char a; a 与 &a 什么类型变量保存 &a. 理解指针的含义. 指针与指针的指针. 指针的初始化. #include "stdio.h" void main() { int a,*p=&a;/* 初始化给 p 赋值 &a, 正确* / int b,*q=b;/* 初始化,类型不匹配错误* /

Télécharger la présentation

本章主要内容

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 指针

  2. 本章主要内容 • 指针的含义 • 指针使用 • 不同类型指针的区别 • 指针与数组的关系 • 动态单元分配 • 复杂指针(选学) • 二维数组的地址 • 指针数组 • 指针的指针 • 数组指针

  3. 指针的含义 • char a; • a与&a • 什么类型变量保存&a

  4. 理解指针的含义

  5. 指针与指针的指针

  6. 指针的初始化 • #include "stdio.h" • void main() • { int a,*p=&a;/*初始化给p赋值&a,正确*/ • int b,*q=b;/*初始化,类型不匹配错误*/ • p=a;/*赋值语句,类型不匹配错误*/ • p=&a;/*赋值语句,正确*/ • *p=a;/*赋值语句,正确*/ • }

  7. 指针的声明与使用举例-1 • #include "stdio.h" • void main() • { int a,b,*p; • a=20;b=30; • p=&a;*p=50; • printf("a=%d,b=%d\n",a,b); • p=&b; scanf("%d%d",&a,p); • printf("a=%d,b=%d\n",a,b); • }

  8. 指针使用举例-2 • #include "stdio.h" • void main() • { char a[10]="abcd",*p=a; • puts(p); • *p='A'; • puts(p); • printf("%c,%s\n",*p,p); • scanf("%s",p); • puts(a); • }

  9. 指针使用举例-3 • #include <iostream.h> • void main(){ • int a,b,*pa=&a,*pb=&b,t,*pt; • cin>>a>>b;//输入20 30 • //比较并理解这两行有何不同,同时只使用一行 • if(*pa<*pb){t=*pa,*pa=*pb,*pb=t;} • //if(*pa<*pb){pt=pa;pa=pb;pb=pt;} • cout<<*pa<<","<<*pb<<","<<a<<","<<b<<endl; • }

  10. 使用指针注意事项 • 有声明:int a=2,*p;下面哪条语句正确 • *p=a; • p=&a; • 有声明:char *p;下面哪条语句正确 • strcpy(p,”ABC”); • p=“ABC”; • scanf(“%s”,p);

  11. 不同类型指针含义 • //运行程序: • #include <stdio.h> • void main() • { char *cp,c[10]; • short int *sp,s[10]; • long *lp,l[10]; • cp=c;sp=s;lp=l; • printf("%p,%p;%p,%p\n",&c[0],&c[1],cp,cp+1); • printf("%p,%p;%p,%p\n",&s[0],&s[1],sp,sp+1); • printf("%p,%p;%p,%p\n",&l[0],&l[1],lp,lp+1); • } • 分析: • //运行程序可以看出,不同类型指针,步长不同,同是加1操作,char 指针变化1,short 指针变化2,long指针变化4,正好是一个本类型单元占据的字节数 • //指针加1与数组下标加1地址相对应

  12. 图示不同类型指针含义

  13. 指针与数组之间的关系 • 从前面很多例子可以看出,int a[10];数组名a中保存着数组的首地址,因此也可以用 *a *(a+i)形式访问数组元素 • 指针与数组相同点: • 指针与数组保存的都是地址值,所以在C语言中,可以互换访问方式,*(p+i) p[i] 两种表达形式是完全相同的 • 指针与数组不同点: • 数组是地址常量,不能改变自身的值,如:int a[10];执行a++或a=p都是错的 • 指针是地址变量,可以随时改变自身的值,但是,指针没有分配保存目标类型的单元,必须指向已分配单元时才能使用,如: • int *p;*p=20;(错) int a,*p=&a;*p(对)

  14. 指针与数组 • #include <iostream.h> • void main(){ • int a[10]={11,22,33,44,55,66,77,88,99,100},*p,i; • p=a;//p=&a[0]; • for(i=0;i<10;i++)cout<<a[i]<<","; • //a[i]替换成下列形式:*a,*(a+i),*(p+i),*p++,p[i], • //错误形式 *a++; • cout<<endl; • p=&a[3]; • for(i=0;i<10;i++)cout<<p[i]<<","; • cout<<endl; • }

  15. 指针与数组的区别 • #include <stdio.h> • void main(){ • char a[]="ABCD";/*给a数组填充字符串"ABCD" 正确*/ • char *p="EFGH";/*让p获得字符串"EFGH"的首地址 正确*/ • a++;/*试图改变地址常量 错误*/ • p++;/*改变指针 正确*/ • a="abcd";/*试图改变地址常量 错误*/ • p="efgh";/*改变指针,让p获得字符串”efgh”的首地址 正确*/ • }

  16. 指针与字符串举例1 • #include "stdio.h" • void main() • { char a[]="ABCDEFG",*p=a; • while(*p)puts(p++); • }

  17. 指针与字符串举例2 • #include "stdio.h" • #include "string.h" • void main() • { char a[]="ABCDEFG"; • char *p,*q,t; • p=a; • q=a+strlen(a)-1; • while(p<q){ • t=*p;*p=*q;*q=t; • p++;q--; • } • puts(a); • }

  18. 内存的动态分配

  19. stdlib.h提供的malloc函数 • 分配函数格式:void * malloc(int size) • 释放函数格式:free(首地址指针) • 举例: • int *p; p=(int *) malloc(10*sizeof(int));……free(p); • 说明: • malloc函数返回void指针,因此,如果需要某种类型指针,需要强制类型转换 • 函数参数为要求分配字节数,需要自己计算 • 使用结束后要用free函数释放, 否则无法再被使用 • 在释放前不要改变首指针的值,否则这块内存会成为内存中的隐藏碎片,无法再使用

  20. stdlib.h提供的calloc函数 • 分配函数格式:void * calloc(int n,int size) • 释放函数格式:free(首地址指针) • 举例: • int *p; • p=(int*)calloc(10,sizeof(int)); • …… • free(p);

  21. malloc举例 • #include "stdio.h" • #include "stdlib.h" • void main() • { int *p,*q,i; • p=(int *)malloc(10*sizeof(int)); • for(i=0;i<10;i++)scanf("%d",&p[i]);/*改为*p++则失去首地址*/ • q=p+9; • for(i=0;i<10;i++)printf("%d ",*q--); • printf("\n"); • free(p); • }

  22. 使用C++运算符new • 分配指令格式: new 类型名 • 释放指令格式:delete 指针 • #include <iostream.h> • void main() • { int *p,*q; • p=new int; • q=new int[10]; • delete p; • delete q; • }

  23. 辨别P++,*p++,(*P)++,*(P++)++*p,*++p • #include "iostream.h" • void main() • { int a[2],*p; • cout<<"array add:"<<a<<endl; • a[0]=1;a[1]=10;p=a; • *p++;cout<<"p="<<p<<" value:"<<*p<<" a[0]="<<a[0]<<" a[1]="<<a[1]<< endl; • a[0]=1;a[1]=10;p=a; • (*p)++;cout<<"p="<<p<<" value:"<<*p<<" a[0]="<<a[0]<<" a[1]="<<a[1]<< endl; • }

  24. 复杂指针 (选学)

  25. 二维数组中的地址 • #include <iostream.h> • void main(){ • int a[3][4],i,j; • for(i=0;i<3;i++){ • for(j=0;j<4;j++) • cout<<&a[i][j]<<"\t"; • cout<<endl; • } • cout<<endl; • for(i=0;i<3;i++)cout<<a[i]<<"\t"<<a[i]+1<<endl; • cout<<endl; • cout<<a<<"\t"<<(a+1)<<endl; • }

  26. 二维数组中的地址

  27. 二维数组中的地址

  28. 二维数组中的地址 • 如有声明 int a[3][4]下面表达式的含义 • #include <iostream.h> • void main(){ • int a[3][4],i,j; • for(i=0;i<3;i++){ • for(j=0;j<4;j++){ • a[i][j]=i*1000+j*100; • cout<<&a[i][j]<<":"<<a[i][j]<<"\t"; • } • cout<<endl; • } • cout<<"*a\t"<<*a<<endl; • cout<<"*(a+1)\t"<<*(a+1)<<endl; • cout<<"*a+1\t"<<*a+1<<endl; • cout<<"**a\t"<<**a<<endl; • cout<<"*(*(a+0)+0)\t"<<*(*(a+0)+0)<<endl; • cout<<"**a+1\t"<<**a+1<<endl; • cout<<"*(*a+1)\t"<<*(*a+1)<<endl; • cout<<"**(a+1)\t"<<**(a+1)<<endl; • cout<<"*(*(a+1)+1)\t"<<*(*(a+1)+1)<<endl; • cout<<"*(*(a+1)+5)\t"<<*(*(a+1)+5)<<endl; • cout<<"*a[2]\t"<<*a[2]<<endl; • cout<<"(*a)[2]\t"<<(*a)[2]<<endl; • cout<<"(*a+1)[2]\t"<<(*a+1)[2]<<endl; • cout<<"(*(a+1))[2]\t"<<(*(a+1))[2]<<endl; • cout<<"*a[2]+1\t"<<*a[2]+1<<endl; • }

  29. 指针数组 • 指针数组是连续的地址单元,如int *b[10];声明了10个指针,而b本身是和指针的的指针同类型的地址量,举例: • #include <iostream.h> • void main() • { int a[10][3],*s,*b[10],i,j; • s=&a[0[0]; • for(i=0;i<30;i++)*s++=i; • for(i=0;i<10;i++)b[i]=a[i]; • for(j=0;j<3;j++) • { for(i=0;i<10;i++)cout<<*b[i]++<<" "; • cout<<endl; • } • }

  30. 指针的指针 • 指针的指针是保存指针单元地址的单元 • #include <iostream.h> • void main() • { int a,*p,**pp; • a=20; • p=&a; • pp=&p;//or *pp=p; • **pp=50; • cout<<a<<endl; • }

  31. 指针的指针举例 • #include <stdio.h> • void main(){ • int **pp; • int *p,a=1; • p=&a;/*p指向a*/ • pp=&p;/*pp指向p*/ • printf("a=%d\n",**pp);/*输出a的内容*/ • int b[2]={2,3}; • p=b;/*p指向b[0]*/ • p++;/*p指向b[1]*/ • printf("b[1]=%d\n",**pp);/*输出b[1]的内容*/ • int c[3][2]={4,5,6,7,8,9},*pa[3]; • pa[0]=c[0];pa[1]=c[1];pa[2]=c[2];/*指针数组获得a[i]*/ • pp=pa;/* pp指向指针数组首地址*/ • printf("c[0][0]=%d\n",**pp);/*输出a[0][0]*/ • printf("c[0][1]=%d\n",*(*pp+1));/*输出a[0][0]*/ • printf("c[1][0]=%d\n",**(pp+1));/*输出a[0][0]*/ • printf("c[1][1]=%d\n",*(*(pp+1)+1));/*输出a[0][0]*/ • }

  32. 数组指针 • 从前面可以看出,int a[5][10]; a是一个特殊的地址,a保存着a[0]、a[1]、a[2]、a[3]、a[4]一维数组的首地址,每加1,则指向下一个数组,要保存这种地址需要的变量就是数组指针 • 声明举例:int (*p)[10]; • p是指向每个对象都是拥有10个整形单元数组 • 对比:int *a,(*b)[10]; • a指向的对象是4个字节的整形单元 • b指向的对象是40个字节的数组

  33. 复杂指针综合举例 • #include <iostream.h> • void main(){ • int a[3][4],i,j; • int *p[3];//指针数组,定义三个整型指针 • int (*q)[4];//数组指针,定义一个指乡数组的指针 • int **r;//定义一个指向整型指针的指针 • for(i=0;i<3;i++) • for(j=0;j<4;j++)a[i][j]=i*10+j; • cout<<*(a[0]+5)<<endl; • p[0]=a[0];//a[0],*p[0]都是整型指针 • for(i=0;i<12;i++)cout<<*p[0]++<<" "; • cout<<endl; • q=a;//a指向[3]数组的指针 • for(i=0;i<3;i++)cout<<**q++<<" "; • cout<<endl; • p[0]=a[0];p[1]=a[1];p[2]=a[2]; • for(i=0;i<3;i++)cout<<p[i]<<" ";//输出连续三个整型指针的地址 • r=&p[0];//r指向指针数组首地址 ,,,r=&a[0]将产生错误 • cout<<endl; • for(i=0;i<3;i++)cout<<*r++<<" ";//输出连续三个整型指针的地址 • cout<<endl; • r=&p[0];//r指向指针数组首地址 • for(i=0;i<3;i++)cout<<* *r++<<" ";//输出连续三个整型指针的地址所指的整数 • cout<<endl; • //r=a;//worng • //r=q;//wrong • }

  34. 复杂指针综合举例

More Related