【文档说明】计算机程序设计基础精讲多练第章课件.ppt,共(48)页,927.734 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-76454.html
以下为本文档部分文字说明:
Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.第六章指针和
引用Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.3教学目标(1)了解指针类型及引用类型的概念及二者的关系与区别;(2)了解指针与引用变量的使用
与操作方法;(3)了解用指针访问变量、数组、字符串的方法。Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePt
yLtd.4基本内容6.1指针6.2指针与数组6.3引用Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.56.1指针6
.1.1地址6.1.2指针的定义6.1.3指针的初始化6.1.4指针的使用6.1.5函数的传址调用方式Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright200
4-2011AsposePtyLtd.66.1.1地址•计算机的内存储器就象一个一维数组,每个数组元素就是一个存储单元。•地址是存放信息数据的内存单元的编号。•程序中定义的任何变量、数组或函数等,在编译时都会在内存中分配一个确定的地址单元。Evaluationonly.eatedwit
hAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.7如何表示地址?•凡是存放在内存中的程序和数据都有一个地址,可以用它们占用的那片存储单元中的第一个存储单元的地址表示。•C++规定:
变量的地址:可以用取地址运算符‘&’来获取数组的地址:可以用数组名表示函数的地址:可以用函数名表示Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyrig
ht2004-2011AsposePtyLtd.8例6-1:取地址运算符&和指针运算符*#include<iostream>usingnamespacestd;intmain(){intx=100;cout<<"变量的值是:"<<x<<endl;cout<
<"变量的所在的地址是:"<<&x<<endl;cout<<"该地址所存储的变量值为:"<<*(&x)<<endl;return0;}Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.
2.0Copyright2004-2011AsposePtyLtd.96.1.2指针的定义数据类型*指针变量名;例:int*ptr;float*array;char*s1,*s2;说明:数据类型是指针所指向变量的类型;*是一个说明符,它不是指针变量名的一部分
,而是表示这里说明的是一个指针;指针变量名是指针变量的名字Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.106.1.3指针的
初始化指针在定义后必须初始化才能使用;否则,结果不确定。指针初始化的一般格式:数据类型*指针变量名=初始地址值;或数据类型*指针变量名;指针变量名=数据对象地址;其中数据对象地址可以是变量、数组、函数、结构等的地址。如:intx=7;int*ptr=&x;//指向
单个变量char*sp;sp=“string”;//指向字符串inta[5],*ap;ap=a;//指向数组intmax(),(*fp)();fp=max;//指向函数编程中常用的初始化方法:int*ptr=NULL;
//初始化为空指针7x&xptrEvaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.116.1.4指针的使用//例6-2:
通过指针访问变量#include<iostream>usingnamespacestd;intmain(){intx=7;int*ptr;ptr=&x;cout<<"x="<<x<<'\t'<<"&x="<<&
x<<endl;cout<<"*ptr="<<*ptr<<'\t'<<"ptr="<<ptr<<endl;*ptr=9;cout<<"x="<<x<<'\t'<<"&x="<<&x<<endl;cout<<"*ptr="<<*ptr<<'\t'<<"ptr="<<pt
r<<endl;return0;}7x7x0x0012FF7Cptr通过变量名直接使用变量x通过指针ptr间接使用变量x0x0012FF7C0x0012FF7CEvaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2
.0Copyright2004-2011AsposePtyLtd.126.1.5函数的传址调用方式实参与形参有3种结合方式:值调用、传址调用和引用调用传址调用赋予了函数操作“异地”数据的权利,对函
数的独立性有一定影响传址调用可实现多值传递使用传址调用方式时,被调用函数的形参是指针,与之对应的实参要用地址值。Evaluationonly.eatedwithAspose.Slidesfor.NET3.5Clie
ntProfile5.2.0Copyright2004-2011AsposePtyLtd.13例6-3交换两个变量的值算法:交换两个变量x和y的值一定要用到第三个变量t作周转:t=x;x=y;y=t;Evaluationonly.eatedwithAsp
ose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.14交换两个变量的值(修改前的程序)voidswap(intx,inty){inttmp;tmp=x;x=y;y=tmp;}intmain(){in
tx=2,y=3;cout<<“x=“<<x<<“,y=“<<y<<endl;swap(x,y);cout<<"Afterexchangex&y:”<<endl;cout<<“x=“<<x<<“,y=“<<y<<endl;return0;}Evaluationo
nly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.15交换两个变量的值(修改后)#i
nclude<iostream>usingnamespacestd;voidswap(int*xp,int*yp){inttmp;tmp=*xp;*xp=*yp;*yp=tmp;}intmain(){inta=2,b=3;cout<<"Beforeexcha
nge:a="<<a<<",b="<<b<<endl;swap(a,b);swap(*a,*b);swap(&a,&b);cout<<"Afterexchange:a="<<a<<",b="<<b<<endl;return0;}运行结果:Beforee
xchange:a=1,b=2Afterexchange:a=2,b=1Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposeP
tyLtd.166.2指针与数组6.2.1指针与一维数组6.2.2指针与字符串Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011Asp
osePtyLtd.176.2.1指针与一维数组计算机中处理数组时,实际上是将a[i]转换成*(a+下标表达式值)的形式。即a[i]*(a+i)因为数组名可以表示该数组的首地址,所以:a[i]*(a+i)*(ptr
+i)其中,ptr是指向a的指针。由此可见,用指针处理数组及元素是最快捷的方式Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.18
例6-4用多种方法输出数组元素#include<iostream>usingnamespacestd;intmain(){inta[]={1,2,3,4,5};//int*ptr;//ptr=a;for(inti=0;i<5;i++)cout<<a[i]<<
"\t";//一般方法:使用数组名和下标//cout<<*(a+i)<<"\t";//使用数组名和指针运算/*{cout<<*ptr<<"\t";//使用指针变量的方法ptr++;}*/cout<<endl;return0;}Evaluat
iononly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.19直接和间接使用变量a[0]a[1]a[2]a[3]a[4]*ptr*(ptr+1)*(p
tr+2)*(ptr+3)*(ptr+4)ptrptr+1ptr+2ptr+3ptr+4ptrptr+1ptr+2ptr+3ptr+4等价Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5
.2.0Copyright2004-2011AsposePtyLtd.206.2.2指针与字符串指针---字符数组(字符串)例题分析设char*string;charstring1[4];string=string1;有string1[0]=
=*stringstring1[1]==*(string+1)Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.21例6-5:计算字符串长度#incl
ude<iostream>usingnamespacestd;intmystrlen(char*string){char*ptr=string;while(*ptr!='\0')ptr++;//指针后移,直到指向字符串结束标志returnptr-
string;}intmain(){charstr[]="HowlongamI?";cout<<str<<"的长度是"<<mystrlen(str)<<endl;return0;}Evaluationonly.eatedwithA
spose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.226.3引用6.3.1引用的概念6.3.2函数的引用调用方式Evaluationonly.eatedwithAspose.S
lidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.236.3.1引用的概念引用是一种特殊类型的变量,可以被认为是另一个变量的别名。引用运算符“&”用来说明一个引用。数据类型&引用名=已
定义的变量名例:inta=10;int&i=a;i=i+100;Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-201
1AsposePtyLtd.24*和&注意:*和&出现在声明语句和执行语句中其含义不同。例如:int*ptr;y=*ptr;int&ref;ptr=&x;*ptr=2;//说明符:声明ptr是一个int型指针//指针运算符:取指
针ptr所指向地址内存储的数值//说明符:声明一个int型的引用ref//地址运算符:取变量x的地址Evaluationonly.eatedwithAspose.Slidesfor.NET3.5Clien
tProfile5.2.0Copyright2004-2011AsposePtyLtd.256.3.2函数的引用调用方式实参与形参有3种结合方式:值调用、传址调用和引用调用在形参名前加上引用说明符“&”即将其声明为引用,实参则直接采用一般的变量名。在函数调用时,形参就
成了实参的别名,对引用的操作就等同于直接对主调函数中原变量的操作。Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.26#include<
iostream>usingnamespacestd;voidswap(int&x,int&y){inttmp=x;x=y;y=tmp;}intmain(){inta=1,b=2;cout<<"Beforeexchange:a="<<a<<",b="<<b<<e
ndl;swap(a,b);cout<<"Afterexchange:a="<<a<<",b="<<b<<endl;return0;}交换两个整形变量的值(引用调用)运行结果:Beforeexchange:a=1,
b=2Afterexchange:a=2,b=1Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.27扩展阅读6
.4动态存储分配6.5自定义数据类型6.5.1结构体类型6.5.2枚举类型Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.286
.4动态存储分配运算符new用来申请所需的内存指针=new数据类型(初值);运算符delete用于释放先前申请到的存储块delete指针;例:int*p=newint(5);deletep;为数组申请动态
内存:指针=new数据类型[数组元素个数];释放数组占用的动态内存空间:delete[]指针;例:int*p=newint[size];delete[]p;Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Cop
yright2004-2011AsposePtyLtd.29例6-8:用动态数组来求斐波那挈数列的前n项#include<iostream>usingnamespacestd;intmain(){intn;cout<<
"求斐波那挈数列的前n项,请输入n:";cin>>n;int*p=newint[n+1];p[0]=0;p[1]=1;cout<<p[0]<<'\t'<<p[1]<<'\t';for(inti=2;i<=n;i++){p[i]=p[i-2]+p[i-1]
;cout<<p[i]<<'\t';}delete[]p;//释放数组空间return0;}Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd
.306.5自定义数据类型6.5.1结构体类型6.5.2枚举类型Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright20
04-2011AsposePtyLtd.31构造类型数据各元素是属于同一个类型的——数组。不同类型的数据组合成一个有机的整体,以便于引用。这些组合在一个整体中的数据是互相联系的。例如,学生信息:学号、
姓名、性别、各科成绩,地址等这些项都与某一学生相联系。如下图所示:可以看到性别(sex)、年龄(age)、成绩(score)、地址(addr)都属于学号为20090531和名为“LeiFen”的学生。如
果将num、name、sex、age、score、addr分别定义为互相独立的简单变量,难以反映它们之间的内在联系。6.5.1结构体类型Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientPr
ofile5.2.0Copyright2004-2011AsposePtyLtd.32结构体作为一种数据构造类型,在程序中使用时要经历定义——声明——调用三个过程。结构体的定义就是对结构体的结构进行描述结构体是由不同的数据类型的数据组成的。组成结构
体的每个数据称为该结构体的成员项,简称成员。structStudent{intid;//学号charname[20];//姓名floatscore;//成绩};struct结构体类型名{数据类型成员变量1;数据类型成员变量2;……数据类型成员变量n;};结构体类型的定义Evalua
tiononly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.33(1)先定义结构体类型,再声明
结构体变量。例如,structDate//定义日期类型{intda_year;intda_mon;intda_day;};Dateyesterday,today,tomorrow;//说明了3个日期类型的变量(2)定义类型的同时声明变量。例如,structDate{intda_year;i
ntda_mon;intda_day;}yesterday,today,tomorrow;(3)直接定义结构体类型变量,不出现结构体类型名。结构体变量的声明Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProf
ile5.2.0Copyright2004-2011AsposePtyLtd.34结构体变量的使用结构体类型变量的成员变量的引用方法为:结构体类型变量名.成员变量名通过指针访问结构体的成员要用箭头操作符->结构体指针变量名->成员变量名例:Studentstu1
,stu2,*ptr=&stu2;stu1.id=20086035;ptr->id=20091001;Evaluationonly.eatedwithAspose.Slidesfor.NET3.5Cli
entProfile5.2.0Copyright2004-2011AsposePtyLtd.35结构体的初始化可采用以下任意一种方式:先声明结构体变量,再赋初值Studentstu1;stu1.id=20086035;s
trcpy(stu1.name,"Zhang3");stu1.score=96;声明时赋值:在声明结构体变量的同时对其赋初值Studentstu2={20091001,"Li4",85.5};注意:不能在定义结构体类型时给成员变量赋值
Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.//例6-9
:学生信息--结构体#include<iostream>#include<cstring>usingnamespacestd;structStudent{intid;//学号charname[20];//姓名floatscore;//成绩};intmain(){Studentstu1,stu2
={20091001,"Li4",85.5};stu1.id=20086035;strcpy(stu1.name,"Zhang3");stu1.score=96;cout<<"第1个学生信息:"<<stu1.id<<"\t"<<stu1.name<<"\t"<
<stu1.score<<endl;cout<<"第2个学生信息:"<<stu2.id<<"\t"<<stu2.name<<"\t"<<stu2.score<<endl;stu2=stu1;cout<
<"复制后第2个学生信息变为:"<<endl;cout<<"第2个学生信息:"<<stu2.id<<"\t"<<stu2.name<<"\t"<<stu2.score<<endl;return0;}Evaluationonly.eatedwithA
spose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.37如果某个数据项只可能取少数几种可能的值,则可将该数据
项定义为枚举类型数据。格式如下:enum枚举类型名{枚举符号表};例:enumSexType{male,female};enumWeekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat};enumGame{win,lose,tie};6.5.
2枚举类型Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.38枚举变量的声明和使用语法形式如下:枚举类型名枚举变量名;例如:Weekdaytoday
;today=Wed;每个枚举元素实际上是一个以其所在位置顺序为值的常量(0,1,2,…),其取值为某一个整数值,所以枚举类型无法直接输出。要想获得变量的符号值,须采用间接方法。Evaluationonly.e
atedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.//例6-10:枚举类型的用法enumSexType{male,fem
ale};structStudent{intid;//学号charname[20];//姓名SexTypesex;//性别floatscore;//成绩};intmain(){Studentstu1={20086035,"Zhang3",male,96};co
ut<<"学生信息:"<<stu1.id<<"\t"<<stu1.name<<"\t"<<stu1.score<<"\t"<<stu1.sex<<endl;cout<<"学生信息:"<<stu1.id<<"\t"<<stu1.name<<"\t"<<stu1.score<<"
\t";switch(stu1.sex){casemale:cout<<"男"<<endl;break;casefemale:cout<<"女"<<endl;break;default:break;}return0;}运行结果
:学生信息:20086035Zhang3960学生信息:20086035Zhang396男Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011
AsposePtyLtd.40上机指导6.6注释号在调试中的作用6.7条件编译Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copy
right2004-2011AsposePtyLtd.41应用举例例6-12使用指针编写一个对整型数组进行排序的函数,排序方法使用冒泡排序法。算法讨论:冒泡排序法是将相邻的元素进行比较,如果不符合所要求的顺序,则交
换这两个元素,对整个数列中所有的元素都进行这种比较,直到所有的元素都排好序为止。Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2
.0Copyright2004-2011AsposePtyLtd.//例6-12:冒泡排序程序#include<iostream>usingnamespacestd;voidbubbleup(int*ptr,intcount){for(inti=0;i<co
unt;i=i+1)for(intj=count-1;j>i;j=j-1)if(*(ptr+j-1)>*(ptr+j)){inttmp=*(ptr+j-1);*(ptr+j-1)=*(ptr+j);*(ptr+j)=tmp;}}
intmain(){intlist[]={53,7,12,61,90,70,87};inti;cout<<"排序前:";for(i=0;i<7;i++)cout<<list[i]<<'\t';bubbleup(list,7);cout<<endl<
<"排序后:";for(i=0;i<7;i++)cout<<list[i]<<'\t';cout<<endl;return0;}Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2
.0Copyright2004-2011AsposePtyLtd.43应用举例例6-13用指针编写一个程序,要求不仅能够统计一个字符串中字符的个数,还能分别指出其中大、小写字母、数字以及其他字符的个数。分析:通过定义一个指向字符数组的指针,对字符串中每一个字符都按照ASCII码
表中的编码进行判断,确定其所属的类别并进行计数,直到整个字符串结束为止。Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.#include<io
stream>usingnamespacestd;intmain(){charstr[]="Current:Clear,Wind:Eat6km/h,Humidity:30%";char*ptr=str;//使指针ptr指向字符数组strinttotal,capital,small,numeral,
others;//定义各种计数器变量total=capital=small=numeral=others=0;//初始化所有计数器变量while(*ptr!='\0')//如果*ptr==0则表示字符串结束{total++;//总字符数if(*ptr>
='A'&&*ptr<='Z')capital++;//若为大写字母,则相应计数加1elseif(*ptr>='a'&&*ptr<='z')small++;//小写字母计数加1elseif(*ptr>='0'&&
*ptr<='9')numeral++;//数字计数加1elseothers++;//其他字符计数加1ptr++;//下一个字符}cout<<"字符串:"<<str<<endl;cout<<"包含大写字母个数:"<<capital<<endl;cout<<"
包含小写字母个数:"<<small<<endl;cout<<"包含数字字符个数:"<<numeral<<endl;cout<<"包含其它字符个数:"<<others<<endl;cout<<"总共含有的字符数:"<<total<<endl
;return0;}Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.4
5voidmystrcpy(char*destin,char*source){while(*source!=0)//若*source==0则表示原字符串结束{*destin=*source;//复制字符source++;//source移向原字符串中的下一个字符
destin++;//destin移向新字符数组的下一位置}*destin=0;//在新字符串尾部添写一个结束符0}例6-14字符串复制Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyri
ght2004-2011AsposePtyLtd.46应用举例例6-15编写一个函数,用于去掉字符串前面的空格,并用主函数进行验证。分析:令指针指向字符串首地址逐个判断字符串前面的字符是否为空格。如是,则向后移动指针继续判断,直到第一个非空格的字符
出现将从该指针开始的字符串复制回原字符串Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-2011AsposePtyLtd.#include<iostream>#include
<cstring>usingnamespacestd;char*myltrim(char*string){char*ptr=string;while(*ptr=='')ptr++;strcpy(string,ptr);returnstring;}intmain(){chars
tr[]="WhoisBuddha?";cout<<"截取前的原始字符串是:["<<str<<']'<<endl;cout<<"截取空格后的字符串是:["<<myltrim(str)<<']'<<endl;return0
;}运行结果:截取前的原始字符串是:[WhoisBuddha?]截取空格后的字符串是:[WhoisBuddha?]Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfile5.2.0Copyright2004-201
1AsposePtyLtd.48学好程序设计语言的唯一途径是你的编程能力与你在计算机上投入的时间成结束语Evaluationonly.eatedwithAspose.Slidesfor.NET3.5ClientProfi
le5.2.0Copyright2004-2011AsposePtyLtd.