slide1
Download
Skip this Video
Download Presentation
本章主要内容

Loading in 2 Seconds...

play fullscreen
1 / 34

本章主要内容 - PowerPoint PPT Presentation


  • 92 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' 本章主要内容' - winter-walton


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide2
本章主要内容
  • 指针的含义
  • 指针使用
  • 不同类型指针的区别
  • 指针与数组的关系
  • 动态单元分配
  • 复杂指针(选学)
    • 二维数组的地址
    • 指针数组
    • 指针的指针
    • 数组指针
slide3
指针的含义
  • char a;
  • a与&a
  • 什么类型变量保存&a
slide6
指针的初始化
  • #include "stdio.h"
  • void main()
  • { int a,*p=&a;/*初始化给p赋值&a,正确*/
  • int b,*q=b;/*初始化,类型不匹配错误*/
  • p=a;/*赋值语句,类型不匹配错误*/
  • p=&a;/*赋值语句,正确*/
  • *p=a;/*赋值语句,正确*/
  • }
slide7
指针的声明与使用举例-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);
  • }
slide8
指针使用举例-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);
  • }
slide9
指针使用举例-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;
  • }
slide10
使用指针注意事项
  • 有声明:int a=2,*p;下面哪条语句正确
    • *p=a;
    • p=&a;
  • 有声明:char *p;下面哪条语句正确
    • strcpy(p,”ABC”);
    • p=“ABC”;
    • scanf(“%s”,p);
slide11
不同类型指针含义
  • //运行程序:
    • #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地址相对应
slide13
指针与数组之间的关系
  • 从前面很多例子可以看出,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(对)
slide14
指针与数组
  • #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;
  • }
slide15
指针与数组的区别
  • #include <stdio.h>
  • void main(){
  • char a[]="ABCD";/*给a数组填充字符串"ABCD" 正确*/
  • char *p="EFGH";/*让p获得字符串"EFGH"的首地址 正确*/
  • a++;/*试图改变地址常量 错误*/
  • p++;/*改变指针 正确*/
  • a="abcd";/*试图改变地址常量 错误*/
  • p="efgh";/*改变指针,让p获得字符串”efgh”的首地址 正确*/
  • }
slide16
指针与字符串举例1
  • #include "stdio.h"
  • void main()
  • { char a[]="ABCDEFG",*p=a;
  • while(*p)puts(p++);
  • }
slide17
指针与字符串举例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);
  • }
stdlib h malloc
stdlib.h提供的malloc函数
  • 分配函数格式:void * malloc(int size)
  • 释放函数格式:free(首地址指针)
  • 举例:
    • int *p; p=(int *) malloc(10*sizeof(int));……free(p);
  • 说明:
    • malloc函数返回void指针,因此,如果需要某种类型指针,需要强制类型转换
    • 函数参数为要求分配字节数,需要自己计算
    • 使用结束后要用free函数释放, 否则无法再被使用
    • 在释放前不要改变首指针的值,否则这块内存会成为内存中的隐藏碎片,无法再使用
stdlib h calloc
stdlib.h提供的calloc函数
  • 分配函数格式:void * calloc(int n,int size)
  • 释放函数格式:free(首地址指针)
  • 举例:
    • int *p;
    • p=(int*)calloc(10,sizeof(int));
    • ……
    • free(p);
malloc
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);
  • }
c new
使用C++运算符new
  • 分配指令格式: new 类型名
  • 释放指令格式:delete 指针
    • #include <iostream.h>
    • void main()
    • { int *p,*q;
    • p=new int;
    • q=new int[10];
    • delete p;
    • delete q;
    • }
p p p p p p
辨别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;
  • }
slide24

复杂指针

(选学)

slide25
二维数组中的地址
  • #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;
  • }
slide28
二维数组中的地址
  • 如有声明 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;
  • }
slide29
指针数组
  • 指针数组是连续的地址单元,如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;
    • }
    • }
slide30
指针的指针
  • 指针的指针是保存指针单元地址的单元
  • #include <iostream.h>
  • void main()
  • { int a,*p,**pp;
  • a=20;
  • p=&a;
  • pp=&p;//or *pp=p;
  • **pp=50;
  • cout<<a<<endl;
  • }
slide31
指针的指针举例
  • #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]*/
  • }
slide32
数组指针
  • 从前面可以看出,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个字节的数组
slide33
复杂指针综合举例
  • #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
  • }
ad