您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 第6章2(C语言基础PPT)
第6章指针C程序的变量所存放的数据:数值型数据:整数、实数通过前面的学习,我们已知道:字符型数据:字符、字符串结构型数据:数组、结构体、共用体占有一定长度的内存单元如:intx;x占二字节、二个单元每一个变量都有一个地址,为无符号整数,它不同于一般的整数。问题:能否对地址运算?能否用一个变量保存地址?这些变量具有的性质:§6.1指针的概念一、数据在内存中的存放设:系统分配i的起始地址为2000的单元内存:为一个连续编号(连续地址)且以一个单元为一个字节的连续存贮区。若程序中定义了三个int变量i,j,kinti=–5,j=5,k=10;则:j的起始地址有可能为为2002的单元k的起始地址有可能为2004的单元2000200120022003200420053001–5+5102000ijk当程序中要用它们的值时:y=i+j+k;找到j的地址2002,将2002,20003中的数据5读出;找到k的地址2004,将2004,2005中的数据10读出。分别找到i的地址2000,将2000,2001中的数据–5读出;则系统通过一张变量名与地址对应关系表:直接访问:直接使用存放该数据的变量名。间接访问:如果将某一变量的地址(如i的地址2000)存放到另一个变量x,则可通过x来存取i的值。上述过程称为变量的“直接访问”然后把这些数据进行算术运算。i相当于使用5使用变量如:用pi,pj,pk来存放i,j,k的地址20002002200455103001300330053007200020022004pipjpkijk若要得到变量i的值,可以先访问pi,得到i的地址,再通过该地址找到它i的值。显然,pi与i是通过i的地址联系起来的。定义:一个变量的地址称为该变量的指针。因此,i的指针的值为2000。如:pi就是指针变量。而存放地址(指针)的变量叫做指针变量。一、指针变量的定义形式:表示该变量为指向某类型变量的指针变量。如:intp;(p为指向整型变量的指针)char*s;(s为指向字符型变量的指针)float*t;(t为指向浮点型变量的指针)基类型指针变量名§6.2指针变量的定义和引用重要概念:指针变量也有各种类型(如上面所示),但指针变量的值只能是整型值。指针变量的引用方式:*变量名----表示所指变量的值。变量名----表示指向变量的指针(地址)。若int*p;char*s;float*t;*p=5;*s=‘a’;*t=3.6;但p=p+1;----------------并不代表p=6它代表的是地址+1若有:float*t;且:*t=3.6;设t的地址为2000,则t+12004例:若有:int*p;且:*p=5;设p的地址为2000,则p+12002若有:char*s;且:*s=‘a’;设s的地址为2000,则s+12001二、引用指针变量将一个变量的地址(指针)赋给一个指针变量,用取地址运算符:&inti,j,p;i=3;p=&i;如果将整数赋给地址量p=1000;编译会提出警告性错误,但程序还是能正常运行,这是很危险的。(只能这样赋值:p=1000;)存取指针变量所指向变量(目标变量)的值:用指针运算符*,即:*p为i,&为同级运算符,结合性自右至左。则当&或&在一起时,具有抵消作用则:p=&i相当于p=i如上例:inti,pi=3p=&i例1例2例3三、指针变量作为函数参数但当用地址(指针变量)作参数时,作用为传址,与数组名类似。形参,于是,形参数前面讲过:函数实参传递单向据值的改变不会影响实参。例:swap(intp1,p2){intp;p=p1;p1=p2p2=p;}要求:形参、实参均为地址量。main(){inta,b;intx1,x2;scanf(%d,%d,&a,&b);x1=&a;x2=&b;swap(x1,x2);printf(a=%d,b=%d\n,a,b);}执行过程分析:输入:10,20结果:a=20,b=10指针变量:(实参)指针变量:(形参)1020ab&ap1p2x1x2&b程序中,实参与形参共用同一个内存单元,通过修改地址所指的值来交换数据:2010ab&ap1p2x1x2&b指针变量:(实参)指针变量:(形参)1.注意函数中p为普通变量,并非地址量;2.如果swap函数中的交换语句改为:intp1,p2,p;p=p1;p1=p2;p2=p;则仅将p1,p2的指向改变,函数返回后,p1,p2释放,a、b中的内容依然未改变。调用函数时:&ax1x2&b实参1020abp1p2形参swap(intp1,p2){intp;p=p1;p1=p2;p2=p;}3.不用地址量作参数,不能实现交换,即:main(){inta,b;scanf(%d,%d,&a,&b);swap(a,b);printf(a=%d,b=%d\n,a,b);}4.结论:若要使变量的值通过函数调用而发生改变,则形参必须是指针型,实参为地址量&变量名或指针型。另:全局变量和数组名作为参数也可改变变量的值.§6.3数组的指针及指向数组的指针变量一个变量的地址为该变量的指针。当用一个变量来存放该地址(指针)时,称为指针变量。一个数组元素相当于一个简单变量。于是,亦可用一个指针变量来指向数组元素。不同之处:数组元素连续地占用内存单元,则当一个元素的指针已知时,其它元素的指针亦可知道。定义方法与简单变量指针定义相同,但引用略有不同例:inta[10];intp;/*定义*/p=&a[0];/*将a的第0个元素的地址赋给p*/C语言规定:数组a的首地址即用&a[0]表示,亦可用a表示所以:p=&a[0];和p=a等价一、数组元素指针变量的定义与引用例:#includestdio.hmain(){intal=123,a2=234,a3=345;int*pl,*p2,*p3;intas[3]={1,2,3},*ps[3];pl=&a1;p2=p1+1;p3=p2+1;ps[0]=&as[0];ps[1]=ps[0]+1;ps[2]=ps[1]+1;printf(p1=%ld\np2=%ld\np3=%ld\n,p1,p2,p3);printf(*p1=%ld\n*p2=%ld\n*p3=%ld\n,*p1,*p2,*p3);printf(ps[0]=%ld\nps[1]=%ld\nps[2]=%ld\n,ps[0],ps[1],ps[2]);printf(*ps[0]=%ld\n*ps[1]=%ld\n*ps[2]=%ld\n,*ps[0],*ps[1],*ps[2]);}运行结果:p1=262737918p2=262737920p3=262737922*p1=123*p2=0*p3=320ps[0]=262737896ps[1]=262737898ps[2]=262737900*ps[0]=1*ps[1]=2*p2[2]=3地址a1的值系统给定的值数组元素地址数组元素的值注意:指针变量在未赋值前指向一个不定值例:#includestdio.hmain(){int*p;printf(*p=%d,p=%ld,*p,p);}运行结果:*p=0,p=3842intp=&a[0];或intp=a;(等价于)intp;p=a;不能有这样的语句:p=&a[0];1.由首地址指针来引用数组中的其它元素。设p为a的首地址,p=a,或p=&a[0];×可以在定义指针变量时赋初值:inta[4]={1,2,3,4};p+1为a[1]的地址,若a为int,p+1相当于地址+2,而当a为float时,p+1相当于地址+4.p+1代表的是地址加一指针地址:数组元素a[0]a[1]a[2]b[0]b[1]b[2]papa+1pa+2pbpb+1pb+2200020022004208020842088如:inta[3],*pa;flaotb[3],*pb;pa=a;pb=b;则指针与数组元素的关系为:一般地:p+i代表a[i]的地址.引用a[i]的值:可使用a[i],(p+i),(a+i)例:#includestdio.hmain(){inta[4]={1,2,3,4},*p,i;p=a;i=0;do{printf(*p=%d,p=%ld\n,*p,p);p=p+1i=i+1}}while(i4)运行结果:*p=1,p=269750264*p=2,p=269750266*p=3,p=269750268*p=4,p=269750270例:inta[10],i;intp;p=a;则:(p+i)和a[i]都是取数组元素的值,而p+i可直接指向a[i]。2.在寻找数组元素时,用p+i比a[i++]速度快3.关于指针的运算p++/p––的作用:指针运算符与++,––同级,且自右至左。而p––相当于p=p–1,即指向a[4]若有:inta[10],*p;p=&a[5];则:p++相当于p=p+1,即指向a[6](p)++或(p)––(p)++:将p指向的变量的值自增1;(p)––:将p指向的变量的值自减1。p++相当于(p++)(结合方向:自右向左)若p=&a[0],则*(p++)取出a[0]的值;(++p):首先使pp+1,p指向a[1],(++p)取出a[1]的值。p++与(++p)的含义例:#includestdio.hmain(){inta[5]={11,22,33,44,55},*p;p=&a[0];printf(*p++=%d\n,*p++);printf(*p=%d\n,*p);printf((*p)++=%d\n,(*p)++);printf(*p=%d\n,*p);}运行结果:*p++=11*p=22(*p)++=22*p=23取出a[0]的值指向a[1]的值先取a[1]的值使a[1]的值增加1当实、形参均为数组名时,调用时将实参数组首地址传递(单向)给形参数组,使它们共享内存。例:编写函数,将数组各元素值取反。二、数组名作函数参数#includestdio.hvoidinvert(x,n);main(){inti,a[10]={1,2,3,4,5,6,7,8,9,10}invert(a,10);for(i=0;i10;i++){ifi%4==0printf(\n)printf(a[%d]=%d,,i,a[i]);}}voidinvert(intx[],intn){inti;for(i=0;in;i++)x[i]=–x[i];return;}运行结果:a[0]=1,a[1]=2,a[3]=3,a[4]=4,a[5]=5,a[6]=6,a[7]=7,a[8]=8,a[9]=9,a[10]=10,分析参数传递情况:即:x,a共享同一段内存单元。前面已分析:可用指针表示数组。即:指针运算引用数组元素,于是,可用指针变量作为形参接收实参数组首地址。a[10]:a[0]a[1]a[2]………………a[9]ax‖x[0]‖x[1]………………‖x[9]实参形参函数改为:voidinvert(intx,n){inti;for(i=x;i(x+n);i++)i=–ireturn;}参数传递情况:a[0]a[1]a[2]……a[9]a:xx+1x+9x(x+1)(x+9)…注意:在主函数中也不一定要用数组名a,只要用一指针变量即可。设intp;p=&a[0],则:invert(p,n);即可完成同样功能总结以上情况,有四种参数传递形式:特别需要指出的是:上面四种传递形式实质上是实现了实、形参共用内存单元。(1)实参、形参均为数组名(2)实参为数组名、形参为指针变量(3)实参、形参均为指针变量(4)实参为指针变量,形参为数组名。1.多维数组的地址:将一维数组内容扩充,也可用一指针变量指向多维数组,以二维数组为例。设:staticinta[3][4]={{1,2,3,4},{5,6,7,8
本文标题:第6章2(C语言基础PPT)
链接地址:https://www.777doc.com/doc-3605463 .html