关闭

关闭

关闭

封号提示

内容

首页 8.指针.PPT

8.指针.PPT

8.指针.PPT

上传者: wanroutianze 2011-08-27 评分 0 0 0 0 0 0 暂无简介 简介 举报

简介:本文档为《8.指针ppt》,可适用于高等教育领域,主题内容包含第八章指针第八章指针指针的概念在定义变量时系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型分配一定长度的空间。内存区的每一个字节有一符等。

第八章指针第八章指针指针的概念在定义变量时系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型分配一定长度的空间。内存区的每一个字节有一个编号这就是内存单元的“地址”它相当于旅馆中的房间号。在地址所标志的内存单元中存放的数据这相当于旅馆房间中居住的旅客一样。由于通过地址能找到所需的变量单元我们可以说地址指向该变量单元。因此在C语言中将地址形象化地称为“指针”意思是通过它能找到以它为地址的内存单元。例如定义了整型变量a和b编译系统在对程序编译时给变量a和b分配了内存单元。每个变量都有相应的起始地址。变量与地址程序中:intifloatk内存中每个字节有一个编号地址ik编译或函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象指针与指针变量指针:一个变量的地址指针变量:专门存放变量地址的变量叫~指针指针变量变量的内容变量的地址与*运算符含义含义:取变量的地址单目运算符优先级:结合性:自右向左含义:取指针所指向变量的内容单目运算符优先级:结合性:自右向左两者关系:互为逆运算理解ipointer指针变量它的内容是地址量*ipointer指针的目标变量它的内容是数据ipointer指针变量占用内存的地址直接访问与间接访问直接访问:按变量地址存取变量值间接访问:通过存放变量地址的变量去访问变量例i=直接访问例*ipointer=间接访问例k=i直接访问k=*ipointer间接访问指针变量指针变量与其所指向的变量之间的关系指针变量的定义一般形式:数据类型*指针变量名合法标识符指针的目标变量的数据类型表示定义指针变量不是‘*’运算符例int*p,*pfloat*qchar*name注意:、指针变量前面的*表示该变量是类型为指针型变量。指针变量名是p和p而不是*p和*p。、在定义指针变量时必须指定数据类型。、赋给指针变量的是变量地址而不能是任意类型的数据而且只能是与指针变量的数据类型相同类型的变量的地址。floataint*pointerpointer=a将float型变量的地址赋给数据类型为int的指针变量是错误的。、指针变量中只能存放地址不要将一个整数赋给一个指针变量。指针变量的初始化一般形式:数据类型*指针变量名=初始地址值赋给指针变量例intiint*p=i变量必须已说明过类型应一致例intiint*p=iint*q=p用已初始化指针变量作初值例main(){inti=int*p*p=iprintf(“d”,*p)}危险!例main(){inti=,kint*pp=k*p=iprintf(“d”,*p)}指针变量必须先赋值,再使用例指针的概念main(){intaint*pa=aa=printf("a:dn",a)printf("*pa:dn",*pa)printf("a:xn",a)printf("pa:xn",pa)printf("pa:xn",pa)}运行结果:a:*pa:a:fpa:fpa:f例输入两个数并使其从大到小输出(c)main(){int*p,*p,*p,a,bscanf("d,d",a,b)p=ap=bif(a<b){p=pp=pp=p}printf("a=d,b=dn",a,b)printf("max=d,min=dn",*p,*p)}运行结果:a=,b=max=,min=指针变量作为函数参数函数的参数不仅可以是整型、浮点型、字符型等数据还可以是指针类型它的作用是将一个变量的地址传送到另一个函数中。参数传递方式值传递方式方式:函数调用时,为形参分配单元,并将实参的值复制到形参中调用结束形参单元被释放实参单元仍保留并维持原值地址传递方式:函数调用时将数据的存储地址作为参数传递给形参例交换两个数#include<stdioh>voidmain(){inta=,b=printf(“a=d,b=dn",a,b)swap(a,b)printf(“a=d,b=dn",a,b)}swap(intx,inty){inttt=xx=yy=t}swap(int*p,int*p){intpp=*p*p=*p*p=p}main(){inta,ba=,b=printf(“a=d,b=dn”,a,b)printf(“swapped:n”)swap(a,b)printf(”a=d,b=dn",a,b)}例交换两个数(c)指针与数组指向数组元素的指针变量例intarrayint*pp=arrayp=array或int*p=array或int*p=array数组名是表示数组首地址的地址常量指针的运算指针变量的赋值运算p=a(将变量a地址p)p=array(将数组array首地址p)p=arrayi(将数组元素地址p)p=p(指针变量p值p)不能把一个整数p,也不能把p的值整型变量如inti,*pp=()i=p()指针变量与其指向的变量具有相同数据类型指针的算术运算:pipid(i为整型数d为p指向的变量所占字节数)p,p,pi,pi,p=i,p=i等例p指向int型数则pp例p指向int型数组且p=a则p指向a例intaint*p=ap*p=指针的算术运算:若指针变量p与p都指向同一数组如执行pp结果是两个地址之差除以数组元素的长度。即pp(pp)d假设p指向实型数组元素ap的值为p指向a其值为则pp的结果是()=这个结果是有意义的表示p所指的元素与p所指的元素之间差个元素。pp无实际意义指针变量的关系运算若p和p指向同一数组则p<p表示p指的元素在前p>p表示p指的元素在后p==p表示p与p指向同一元素若p与p不指向同一数组比较无意义通过指针引用数组元素引用一个数组元素可以用:  (1)下标法如a[i]形式  (2)指针法如*(a+i)或*(p+i)。其中a是数组名p是指向数组元素的指针变量其初值p=a。数组元素表示方法ai*(ai)ai*(pi)*(ai)例输出数组中的全部元素。假设有一个a数组整型有10个元素。要输出各元素的值有三种方法:()下标法。()通过数组名计算数组元素地址找出元素的值。()用指针变量指向数组元素。()下标法。(()c)#include<stdioh>voidmain(){inta[10] int i for(i=0i<10i++)  scanf(″%d″&a[i]) printf(″\n″) for(i=0i<10i++)  printf(″%d″a[i])}()通过数组名计算数组元素地址找出元素的值(()c)#include<stdioh>void main(){inta[10] inti for(i=0i<10i++)  scanf(″%d″&a[i])  printf(″\n″) for(i=0i<10i++)  printf(″%d″*(a+i)) }()用指针变量指向数组元素。(()c)#include<stdioh>voidmain(){inta[10] int*pi for(i=0i<10i++)  scanf(″%d″&a[i]) printf(″\n″) for(p=ap<(a+10)p++)  printf(″%d″*p)}main(){inti,*p,ap=afor(i=i<i)scanf("d",p)printf("n")for(i=i<i,p)printf("d",*p)printf("n")}例注意指针的当前值(c)p=a指针变量可以指到数组后的内存单元可以用数组名作函数的参数如:voidmain(){voidf(intarrintn)intarrayf(array,)*实参为数组名array*}voidf(intarr,intn)*形参为数组形式*{}用数组名作函数参数例将数组a中n个整数按相反顺序存放。解题思路:将a与an对换再将a与an对换直到将aint(n)与anint((n)对换。现用循环处理此问题设两个“位置指示变量”i和ji的初值为j的初值为n。将ai与aj交换然后使i的值加j的值减在将ai与aj对换直到i=(n)为止。#include<stdioh>*c*voidmain(){voidinv(intx[]intn)intia[10]={37911067542} printf(″Theoriginalarray:\n″) for(i=0i<10i++) printf(″%d″a[i]) printf(″\n″) inv(a10) printf(″Thearrayhasbeeninverted:n″) for(i=0i<10i++) printf(″%d″a[i]) printf(″\n″)}voidinv(intx[]intn)*形参x是数组名*{inttempijm=(n-1)/2   for(i=0i<=mi++)    {j=n-i-     temp=x[i]x[i]=x[j]x[j]=temp}   return}运行情况如下:Theoriginalarray:37911067542Thearrayhasbeeninverted:24576011973#include<stdioh>voidmain(){voidinv(int*xintn)intia[10]={37911067542} printf(″Theoriginalarray:\n″)  for(i=0i<10i++) printf(″%d″a[i]) printf(″\n″) inv(a10) printf(″Thearrayhasbeeninverted:n″)  for(i=0i<10i++) printf(″%d″a[i]) printf(″\n″)}对刚才的程序可以作一些改动。将函数inv中的形参x改成指针变量“int*x”。(c)voidinv(int*xintn)*形参x为指针变量*{inttemp,*p,*i,*j,m=(n-1)/2i=xj=x+n-1p=x+mfor(i<=pi++j--){temp=*i*i=*j*j=temp} return}归纳起来如果有一个实参数组想在函数中改变此数组中的元素的值实参与形参的对应关系有以下4种情况:()形参和实参都用数组名如:voidmain()voidf(intx]intn){inta[10]{……f(a10)}}()实参用数组名形参用指针变量。如:voidmain()voidf(int*xintn){inta[10]{……f(a10)}}()实参形参都用指针变量。例如:voidmain()voidf(int*xintn){inta[10],*p=a{f(p10)}}()实参为指针变量形参为数组名。如:voidmain()voidf(intxintn){inta[10],*p=a{f(p10)}}#include<stdioh>*c*voidmain(){voidinv(int*xintn)intia[10]*p=a*先使实参指针变量p指向数组a*printf(″Theoriginalarray:n″)for(i=0i<10i++p++) scanf(″%d″p) printf(″\n″)p=ainv(p10)*实参为指针变量*printf(″Thearrayhasbeeninverted:\n″)for(p=ap<a+10p++)printf(″%d″*p)printf(″\n″)}voidinv(int*xintn)*形参x为指针变量*{int*pmtemp*i*j m=(n-1)/2i=xj=x+n-1p=x+m for(i<=pi++j--){temp=*i*i=*j*j=temp} return}例用选择法对10个整数按由大到小顺序排序。(c)#include<stdioh>voidmain(){voidsort(intx[]intn)int*pia[]p=afor(i=0i<10i++)  scanf(″%d″p++)p=asort(p10)for(p=ai=0i<10i++){printf(″%d″*p)p++}}voidsort(intxintn){intijktfor(i=0i<n-1i++) {k=i  for(j=i+1j<nj++)  if(x[j]>x[k]) k=j if(k!=i)  {t=x[i]x[i]=x[k]x[k]=t} }}指针与字符串字符串的表示形式例定义一个字符数组对它初始化然后输出该字符串#include<stdioh>voidmain(){charstring[]=″IloveChina!″printf(″%s\n″string)}()用字符数组存放一个字符串然后输出该字符串。()用字符指针指向一个字符串。可以不定义字符数组而定义一个字符指针。用字符指针指向字符串中的字符。例定义字符指针#include<stdioh>voidmain(){char*string=″IloveChina!″ printf(″sn″string)}说明:在程序中没有定义字符数组只定义了一个字符指针变量string用字符串常量″IloveChina!″对它初始化。C语言对字符串常量是按字符数组处理的在内存中开辟了一个字符数组用来存放该字符串常量但是这个数组是没有名字的不能通过数组名来引用只能通过指针变量来引用。对字符指针变量string初始化实际上是把字符串第个元素的地址(即存放字符串的字符数组的首元素地址)赋给string。说明:printf(″sn″string)s是输出字符串时所用的格式符在输出项中给出字符指针变量名string则系统先输出它所指向的一个字符数据然后自动使string加使之指向下一个字符然后再输出一个字符……如此直到遇到字符串结束标志’’为止。注意:在内存中字符串的最后被自动加了一个’’因此在输出时能确定字符串的终止位置。例有一字符数组a内存有字符串“Iamaboy”要求把该字符串复制到字符数组b中。#include<stdioh>voidmain(){chara=″Iamaboy.″bintifor(i=0*(a+i)!=′\0′i++)*(b+i)=*(a+i)*用指针法访问数组元素**(b+i)=′\0′printf(″stringais:%s\n″a)printf(″stringbis:″)for(i=0b[i]!=′\0′i++) printf(″%c″b[i])*用下标法访问数组元素*printf(″\n″)}运行结果:stringais:Iamaboystringbis:Iamaboy 也可以设指针变量用它的值的改变来指向字符串中的不同的字符。例用指针变量来处理上例问题。#include<stdioh>voidmain(){chara=″Iamaboy″b*p*pinti p1=ap2=bfor(*p1!=′\0′p++p++)*p2=*p1*p2=′\0′printf(“stringais:sn”,a)printf(“stringbis:”)for(i=bi!=‘’i)printf(“c”,bi)printf(“n”)}程序必须保证使p1和p2同步移动字符指针作函数参数例用函数调用实现字符串的复制#include<stdioh>voidmain(){voidcopystring(char*fromchar*to)char*a=″Iamateacher″charb=″youareastudent.″char*p=bprintf(“stringa=snstringb=sn”,a,p)printf(“ncopystringatostringb:n”)copystring(a,p)*用字符指针作实参*printf(“stringa=snstringb=sn"ab)}voidcopystring(char*fromchar*to)*形参是字符指针变量*{for(*from!=‘’fromto)*只要串a没结束就复制到b数组* {*to=*from} *to=’’}程序运行结果如下:stringa=Iamateacher.stringb=youareastudent.copystringatostringb:stringa=Iamateacher.stringb=Iamateacher.字符数组由若干个元素组成每个元素中放一个字符而字符指针变量中存放的是地址(字符串第个字符的地址)决不是将字符串放到字符指针变量中。对使用字符指针变量和字符数组的讨论字符数组和字符指针变量二者之间的区别:()赋值方式。对字符数组只能对各个元素赋值不能用以下办法对字符数组赋值。charstrstr=″IloveChina!″而对字符指针变量可以采用下面方法赋值:char*aa=″IloveChina!″注意:赋给a的不是字符而是字符串第一个元素的地址。()对字符指针变量赋初值:char*a=″IloveChina!″等价于char*aa=″IloveChian!″而对数组的初始化:charstr[14]={″IloveChina!″}不能等价于charstr[14]str[]=″IloveChina!″即数组可以在定义时整体赋初值但不能再赋值语句中整体赋值。()定义了一个字符数组在编译时为它分配内存单元它有确定的地址。而定义一个字符指针变量时给指针变量分配内存单元在其中可以放一个字符变量的地址。也就是说该指针变量可以指向一个字符型数据但如果不对它赋予一个地址值则它并不具体指向一个确定的字符数据。例如:charstr[10] scanf(″s″str)但是:char*ascanf(″s″a)目的是想输入一个字符串编译时发出“警告”信息提醒未给指针变量指定初始值。虽然也能勉强运行但这种方法是危险的决不应提倡。因为编译时虽然给指针变量a分配了内存单元变量a的地址已经指定了但a的值并未指定在a单元中是一个不可预料的值。在执行scanf函数时要求将一个字符串输入到a所指向的一段内存单元中。而a的值如今却是不可预料的它可能指向内存中空白的用户存储区也有可能指向已存放指令或数据的有用内存段这就会破坏了程序甚至破坏了系统会造成严重的后果。正确写法:char*a,stra=strscanf(″s″a)()指针变量的值是可以改变的例如:例 改变指针变量的值#include<stdioh>voidmain(){char*a=″IloveChina!″a=a+7printf(″sn″a)}运行结果:China!#include<stdioh>void main(){char*a=″IloveChina!″intiprintf(“Thesixthcharacterisc\n"a[])()若定义了一个指针变量并使它指向一个字符串就可以用下标形式引用指针变量所指的字符串中的字符。例如:a的值是a所指向的字符串“IloveChina!”中第个字符即字符’e’。字符数组中各元素的值是可以改变的(可以对它们再赋值)但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对它们再赋值)。例如:chara=“House”char*b=“House”a=‘r’*合法r取代u*b=‘r’*非法字符串常量不能改变*使用指针应注意:指针使用太灵活对熟练的程序人员来说可以利用它编写出颇有特色的、质量优良的程序实现许多用其他高级语言难以实现的功能但也十分容易出错而且这种错误往往比较隐蔽。由于指针运用的错误可能会使整个程序遭受破坏比如由于未对指针变量p赋值就向*p赋值就可能破坏了有用的单元的内容。有人说指针是有利有弊的“双刃剑”如果使用指针不当会出现隐蔽的、难以发现和排除的故障。因此在初学时应集中精力掌握最基本最常用的内容首先保证程序的正确性在熟练之后再注重提高技巧。在使用指针时要十分小心谨慎要多上机调试程序深入掌握使用指针的规律注意积累经验。练习题练习题以下程序的输出结果是()main(){chara={""}char*pinti=p=aiprintf("sn",p)}A)B)C)‘’D)B练习题练习题以下程序的输出结果是()main(){inta={,,,,,,,,,},*pp=aprintf("dn",*p)}A)B)C)D)C练习题练习题若有以下程序:main(){charch="Iamstudent!",*pp=chprintf("xn",p)printf("xn",p)}其中第一个printf()运行结果是ffd则第二个printf()运行结果是()。A)ffdfB)ffeC)ffdD)ffcfA练习题练习题以下程序的输出结果是()main(){inti,x={,,,,,,,,},*p=xfor(i=i<i=)printf("d",pi)}A)B)C)D)C练习题练习题请读程序段:charstr=“ABCD”,*p=strprintf("dn",*(p))上面程序段的输出结果是()A)B)C)字符“D”的地址D)不确定的值B

职业精品

用户评论

0/200
    暂无评论

精彩专题

上传我的资料

热门资料

资料评价:

/62
0下载券 下载 加入VIP, 送下载券

意见
反馈

返回
顶部