7 第6章 数组指针与字符串二Word格式文档下载.docx
- 文档编号:4604984
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:59
- 大小:1.13MB
7 第6章 数组指针与字符串二Word格式文档下载.docx
《7 第6章 数组指针与字符串二Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《7 第6章 数组指针与字符串二Word格式文档下载.docx(59页珍藏版)》请在冰点文库上搜索。
}
运行结果:
例6-7
(2)使用数组名和指针运算访问数组元素
//例6_7
(2)使用数组名和指针运算访问数组元素.cpp(P205)
*(a+i)<
例6-7(3)使用指针变量访问数组元素
//例6_7(3)使用指针变量访问数组元素.cpp(P206)
for(int*p=a;
p<
(a+10);
p++)
*p<
6.2.7指针数组
●数组的元素是指针型
例6-8利用指针数组存放矩阵
//例6_8利用指针数组存放矩阵源.cpp(P207)
intline1[]={1,0,0};
//定义数组,矩阵的第一行
intline2[]={0,1,0};
//定义数组,矩阵的第二行
intline3[]={0,0,1};
//定义数组,矩阵的第三行
//定义整型指针数组并初始化
int*pLine[3]={line1,line2,line3};
Matrixtest:
"
<
//输出单位矩阵
3;
i++){//对指针数组元素循环
for(intj=0;
j<
j++)//对矩阵每一行循环
cout<
pLine[i][j]<
}
输出结果为:
指针数组与二维数组对比
●对比例6-8中的指针数组和如下二维数组
int
array2[3][3]
={
{
1,0,0
},
0,1,0
0,0,1
}
};
例6-9二维数组举例
//例6_9二维数组举例.cpp(P208)
intarray2[3][3]={{11,12,13},{21,22,23},{31,32,33}};
for(inti=0;
i++){
for(intj=0;
j++)
*(*(array2+i)+j)<
//逐个输出二维数组第i行元素值
指针与函数
6.2.8以指针作为函数参数
为什么需要用指针做参数?
●需要数据双向传递时(引用也可以达到此效果)
■用指针作为函数的参数,可以使被调函数通过形参指针存取主调函数中实参指针指向的数据,实现数据的双向传递
●需要传递一组数据,只传首地址运行效率比较高
■实参是数组名时形参可以是指针
例6-10读入三个浮点数,将整数部分和小数部分分别输出
//例6_10读入三个浮点数,将整数部分和小数部分分别输出.cpp(P209)
//将实数x分成整数部分和小数部分,形参intpart、fracpart是指针
voidsplitFloat(floatx,int*intPart,float*fracPart){
*intPart=static_cast<
int>
(x);
//取x的整数部分
*fracPart=x-*intPart;
//取x的小数部分
Enter3floatpointnumbers:
floatx,f;
intn;
cin>
>
x;
splitFloat(x,&
n,&
f);
//变量地址作为实参
IntegerPart="
n<
FractionPart="
f<
例6-10-2指向常量的指针做形参
//例6_10_2指向常量的指针做形参.cpp
constintN=6;
voidprint(constint*p,intn);
intarray[N];
for(inti=0;
N;
cin>
array[i];
print(array,N);
6.2.9指针类型的函数
若函数的返回值是指针,该函数就是指针类型的函数。
指针函数的定义形式
存储类型数据类型*函数名()
{//函数体语句
注意
●不要将非静态局部地址用作函数的返回值
■错误的例子:
在子函数中定义局部变呈后将其地址返回给主函数,就是非法地址。
●返回的指针要确保在主调函数中是有效、合法的地址
■正确的例子:
主函数中定义的数组,在子函数中对该数组元素进行某种操作后,返回其中一个元素的地址,这就是合法有效的地址。
在子函数中通过动态内存分配new操作取得的内存地址返回给主函数是合法有效的,但是内存分配和释放不在同—级别,要注意不能忘记释放,避免内存泄漏。
错误的例子
intmain(){
int*function();
int*ptr=function();
*ptr=5;
//危险的访问!
int*function(){
intlocal=0;
//非静态局部变量作用域和寿命都公限于本函数体内
return&
local;
}//函数运行结束时,变量local被释放
正确的例子1
//例6_10_36.2.9指针类型函数正确例子1.cpp
#include<
intarray[10];
//主函数中定义的数组
int*search(int*a,intnum);
for(inti=0;
i<
10;
i++)
cin>
array[i];
int*zeroptr=search(array,10);
//将主函数中数组的首地址传给子函数
int*search(int*a,intnum){//指针a指向主函数中定义的数组
num;
if(a[i]==0)
a[i];
//返回的地址指向的元素是在主函数中定义的
}//函数运行结束时,a[i]的地址仍有效
正确的例子2
//例6_10_46.2.9指针类型函数正确例子2.cpp
int*newintvar();
int*intptr=newintvar();
*intptr=5;
//访问的是合法有效的地址
deleteintptr;
//如果忘记在这里释放,会造成内存泄漏
int*newintvar(){
int*p=newint();
returnp;
//返回的地址指向的是动态分配的空间
}//函数结束运行时,p中的地址仍有效
6.2.10指向函数的指针
函数指针的定义
●定义形式
存储类型数据类型(*函数指针名)();
●含义
函数指针指向的是程序代码存储区
函数指针的典型用途一一实现函数回调
●通过函数指针调用的函数
■例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候可以灵活的使
用不同的方法。
●调用者不关心谁是被调用者
■需知道存在一个具有特定原型和限制条件的被调用函数。
函数指针举例
●编写一个计算函数compute,对两个整数进行各种计算。
有一个形参为指向具体算法函
数的指针,根据不同的实参函数,用不同的算法进行计算。
●编写三个函数:
求两个整数的最大值、最小值、和。
分别用这三个函数作为实参,测试
compute函数。
例6-11-0函数指针举例
//例6_11_0函数指针举例.cpp(P211)
intcompute(inta,intb,int(*func)(int,int))
{returnfunc(a,b);
intmax(inta,intb)//求最大值
{return((a>
b)?
a:
b);
intmin(inta,intb)//求最小值
{return((a<
intsum(inta,intb)//求和
{returna+b;
inta,b,res;
cout<
请输入整数a:
cin>
a;
请输入整数b:
b;
res=compute(a,b,&
max);
Maxof"
a<
and"
b<
is"
res<
endl;
min);
Minof"
sum);
Sumof"
例6-11函数指针实例
//例6_11函数指针实例.cpp(P212)
voidprintStuff(float){
Thisistheprintstufffunction."
voidprintMessage(floatdata){
Thedatatobelistedis"
data<
voidprintFloat(floatdata){
Thedatatobeprintedis"
constfloatPI=3.14159f;
constfloatTWO_PI=PI*2.0f;
intmain(){//主函数
void(*functionPointer)(float);
//函数指针
printStuff(PI);
functionPointer=printStuff;
//函数指针指向printStuff
functionPointer(PI);
//函数指针调用
functionPointer=printMessage;
//函数指针指向printMessage
functionPointer(TWO_PI);
functionPointer(13.0);
functionPointer=printFloat;
//函数指针指向printFloat
printFloat(PI);
6.2.11对象指针
1.对象指针的一般概念
●对象指针定义形式
类名
*对象指针名;
■例:
Pointa(5,10);
Piont*ptr;
ptr=&
●通过指针访问对象成员
对象指针名->
成员名
例:
ptr->
getx()
相当于
(*ptr).getx();
例6-12使用指针来访问Point类的成员
//例6_12使用指针来访问Point类的成员.cpp(P213)
classPoint{//类的定义
public:
//外部接口
Point(intx=0,inty=0):
x(x),y(y){}//构造函数
intgetX()const{returnx;
}//返回x
intgetY()const{returny;
}//返回y
private:
//私有数据
intx,y;
Pointa(4,5);
//定义并初始化对象a
Point*p1=&
//定义对象指针,用a的地址将其初始化
p1->
getX()<
//利用指针访问对象成员
a.getX()<
//利用对象名访问对象成员
利用指针访问对象成员与利用对象名访问对象成员是一致的
2.this指针
●指向当前对象自己
●隐含于类的每一个非静态成员函数中。
●指出成员函数所操作的对象。
■当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。
●例如:
Point类的getX函数中的语句:
returnx;
相当于:
returnthis->
x;
曾经出现过的错误例子
classFred;
//前向引用声明
classBarney{
Fredx;
//错误:
类Fred的声明尚不完善
classFred{
Barneyy;
正确的程序
Fred*x;
一般在软件开发中不会直接用到this指针访问数据成员,有时需要将此对象作为参数传递给某个函数时会使用this指针,亦或是写程序时忘记某个函数名,输入this->
后vs2010会提示出所有成员函数。
3.指向类的非静态成员的指针
类的成员都是变量、对象、函数等,我们同样可以定义存放它们的地址的指针,从而使指针指向对象的成员,通过指针就可以访问对象的成员了。
但是通过这种指向成员的指针一样也只能访问公有成员。
声明指向非静态成员的指针的语法形式为:
类型说明符类名:
:
*指针名;
//声明指向公有数据成员的指针
类型说明符(类名:
*指针名)(形参表);
//声明指向公有成员函数的指针
指向成员的指针也要先声明再赋值,然后才能引用。
给指向成员的指针赋值就是要说明此指针指向类的哪一个成员。
为指向数据成员的指针赋值的语法形式为:
指针名=&
类名:
数据成员名;
在前面的地址相关运算中,我们知道用“&
”运算符可以取到变量的地址,将其赋值给某个指针后就可以通过这个指针访问变量了。
但是对于指向类的数据成员的指针就不同了,在类声明时并不会为类的数据成员分配内存空间,所以给指向数据成员的指针赋值只是确定了此指针指向哪个数据成员,同时也在指针中存放了该数据成员相对于类的起始地址的地址偏移量。
这时通过赋值后的指针不能访问到具体的数据成员。
在声明了类的对象后就会为对象分配内存,这样根据对象的起始地址和指向数据成员的指针中存放的偏移量就可以访问到对象的数据成员了。
通过对象和指向数据成员的指针访问公有数据成员的语法形式为:
对象名.*指向数据成员的指针名
或者
对象指针名->
*指向数据成员的指针名
为指向成员函数的指针赋值的语法形式为:
函数成员名;
在上面的形式为成员函数指针赋值以后还不能直接用此指针调用成员函数,必须先声明了类的对象,再通过对象和指向非静态成员函数的指针调用成员函数。
调用的语法形式为:
(对象名.*指向成员函数的指针名)(形参表)
(对象指针名->
*指向成员函数的指针名)(形参表)
在为成员函数指针赋值时,还有用对象和成员函数指针调用成员函数时,我们都要注意成员函数指针的返回值类型和形参表一定要和指向的成员函数一致。
我们以上面对象指针中6-12Point类的例子为基础修改下,看看访问对象公有成员函数的几种方式:
例6-13访问对象的公有成员函数的不同方式
//例6_13访问对象的公有成员函数的不同方式.cpp(P216)
classPoint{//类的定义
//外部接口
}//返回x
}//返回y
//私有数据
intmain(){//主函数
Pointa(4,5);
//定义对象A
//定义对象指针并初始化
int(Point:
*funcPtr)()const=&
Point:
getX;
//定义成员函数指针并初始化
(a.*funcPtr)()<
//
(1)使用成员函数指针和对象名访问成员函数
(p1->
*funcPtr)()<
//
(2)使用成员函数指针和对象指针访问成员函数
//(3)使用对象名访问成员函数
//(4)使用对象指针访问成员函数
四种不同的访问方式结果都一样
4.指向类的静态成员的指针
对于类的静态成员的访问是不依赖对象的,因此可以用普通指针存放静态成员的地址,通过普通指针来指向和访问它。
下面的例子是将例5-4稍作修改后形成的程序。
例6-14通过指针访问类的静态数据成员
//例6_14通过指针访问类的静态数据成员.cpp(P216)
classPoint{//Point类定义
public:
Point(intx=0,inty=0):
x(x),y(y){//构造函数
count++;
}
Point(constPoint&
p):
x(p.x),y(p.y){//拷贝构造函数
}
~Point(){count--;
intgetX()const{returnx;
intgetY()const{returny;
staticintcount;
//静态数据成员声明,用于记录点的个数
private:
//私有数据成员
intx,y;
intPoint:
count=0;
//静态数据成员定义和初始化,使用类名限定
intmain(){//主函数实现
int*ptr=&
count;
//定义一个int型指针,指向类的静态成员
//定义对象a
PointA:
"
a.getY();
Objectcount="
*ptr<
//直接通过指针访问静态数据成员
Pointb(a);
//定义对象b
PointB:
b.getX()<
b.getY();
例6-15通过指针访问类的静态数据
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第6章 数组指针与字符串二 数组 指针 字符串