c++程序设计谭浩强第6章修订.docx

上传人:b****4 文档编号:27119091 上传时间:2023-06-27 格式:DOCX 页数:40 大小:54.30KB
下载 相关 举报
c++程序设计谭浩强第6章修订.docx_第1页
第1页 / 共40页
c++程序设计谭浩强第6章修订.docx_第2页
第2页 / 共40页
c++程序设计谭浩强第6章修订.docx_第3页
第3页 / 共40页
c++程序设计谭浩强第6章修订.docx_第4页
第4页 / 共40页
c++程序设计谭浩强第6章修订.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

c++程序设计谭浩强第6章修订.docx

《c++程序设计谭浩强第6章修订.docx》由会员分享,可在线阅读,更多相关《c++程序设计谭浩强第6章修订.docx(40页珍藏版)》请在冰豆网上搜索。

c++程序设计谭浩强第6章修订.docx

c++程序设计谭浩强第6章修订

第六章指针

6.1指针的基本概念(P157)

一、地址

1.内存单元的地址

内存单元的基本单位是字节,为了方便对内存的访问,每一个内存单元都有一个编号,这个编号就称为内存单元的地址。

2.内存单元的内容

内存单元中存放的数据即是内存单元的内容。

例:

inti=9,j=6,k=5;

说明:

每当在程序中定义了变量,C或C++编译系统就会根据变量的不同类型,在内存中为其分配相应字节数目的存储空间。

把变量在内存中所占存储单元的首地址,称为该变量的地址(Address)。

把变量在内存中所占存储单元中存放的数据,称为该变量的内容。

而在计算机内存中,对变量值的存取实质上是通过地址进行的。

例6.1观察地址

#include

usingnamespacestd;

intmain()

{intx=55;

cout<<"x="<

cout<<"xaddresis:

="<<&x<

return0;

}

3.“直接访问”与“间接访问”

●按变量名存取变量值的方式称为“直接访问”。

●按变量地址的存放单元存取变量值的方式称为“间接访问”。

例如:

(1)(直接访问)

(2)(间接访问)

二、指针与指针变量

1.指针

一个变量的地址称为该变量的“指针“。

说明:

由于通过地址可以找到所需的变量单元,也即是说,地址“指向“该变量单元,因此,在C或C++中,将地址形象化地称为”指针“。

如:

2000是变量i的指针。

2.指针变量

一种用来存放另一个变量地址值的特殊变量,其值是内存单元的地址。

如:

i_pointer

所谓变量的指针就是变量的地址,而指针变量是用来存放变量的地址。

i_pointeri

2000

在指针变量与他所指向的变量之间存在着一种联系。

三、指针变量的定义(P159)

指针变量也是变量,他具有变量的所有特性。

如:

在内存中占据一定的存储空间,遵循“先定义,后使用”的原则等,但指针变量作为一种特殊的变量,他的内容只能是地址,而不能是数据。

1.指针变量定义的一般形式

类型标识符*指针变量名

例如:

int*pointer_1,*pointer_2;

float*pointer_3;

char*pointer_4;

2.说明

①“*“表示该变量为指针变量(在定义语句中);

②指针变量具有“基类型”,基类型不同的指针变量不能混合使用;

③指针变量在内存中所占的存储空间是一样的(此点与数据类型说明不同)。

例如:

int*pc;

char*px;

pc、px为两个指针变量,分别为指向整型变量和实型变量的指针,作为pc、px本身在内存中所占的存储空间都是一样的。

四、指针变量的赋值与引用(P161~163)

1.指针运算符

①&:

取地址运算符;

②*:

指针运算符(或称“间接访问“运算符)

说明:

①“&”其功能是求出运算量的地址,他要求运算量必须是变量,而不能是表达式、常量等。

例如:

intx=5,*p;

p=&x;//表示把变量x的地址赋给指针变量p(不改变x的值)。

假设,变量x的值为10,其在内存中的地址为3000,则执行上述语句后,p的值为:

3000

注意:

在给指针变量赋地址值时,必须要确保指针变量的基类型与所赋地址值中存放的变量保持类型一致。

例如:

int*p;

charch;

则语句:

p=&ch//是错误的。

②“*”其功能与“&”相反,用于返回一个指针所指对象的内容。

他要求运算对象必须是已被正确初始化或已指向某一确定内存单元的指针变量。

例如:

int*p1,*p2,i=0,j=1;

p1=&i;p2=&j;

则j=*p1等价于:

j=i;//(即j的值变为0)

i=*p1+3等价于:

i=i+3;

2.指针的引用

例6.2通过指针变量的修改来改变被指示变量的值。

#include

usingnamespacestd;

intmain()

{inta=10,b;

int*p;

p=&a;

b=a;

cout<<"a=”<

*p+=10;

cout<<"a=”<

b+=10;

cout<<"a=”<

a=a+10;

cout<<"a=”<

return0;

}

例6.3对比指针变量值的改变与指针变量指向地址内容的改变。

#include

usingnamespacestd;

intmain()

{inta=10,b=20,c=30,d=40;

int*p1=&a;

int*p2=&b;

int*p3=&c;

int*p4=&d;

cout<<"a=”<

cout<<"c=”<

p1=p2;

*p3=*p4;

cout<<"a=”<

cout<<"c=”<

return0;

}

例6.4通过指针变量交换两个变量的值(cex6_41,cex6_42)

/*ctex7_41*/

#include

usingnamespacestd;

intmain()

{inta=10,b=20;

int*p1=&a;

int*p2=&b;

intt;

cout<<"a=”<

{t=*p1;*p1=*p2;*p2=t;}

printf("\nNowa=%d,b=%d,*p1=%d,*p2=%d",a,b,*p1,*p2);

}

/*ctex7_42*/

#include

usingnamespacestd;

intmain()

{inta=10,b=20;

int*p1=&a;

int*p2=&b;

int*t;

cout<<"a=”<

{t=p1;p1=p2;p2=t;}

cout<<"a=”<

}

五、空指针(P185)

1.空指针的含义

所谓“空指针”是指:

指针变量不指向任何变量或数据。

一般而言,“空指针”在以下二种情况下出现:

①定义了一个指针变量,既没有进行初始化,也没有对其进行赋值;

②用一个宏定义NULL为其指针变量赋值。

2.良好的建议:

当定义了一个指针变量,但暂时又不马上使用时,可为他赋一个NULL值(即空值),以明确表示该指针变量目前不指向任何一个存储单元。

例如:

p=NULL;(p为指针变量)

注意:

①NULL是系统在头文件中定义的预定义标识符;

②NULL的拼写必须采用大写字母。

六、指针的运算(P185)

1.算术运算

当指针指向一串连续的存储单元时,可以对指针变量进行加、减一个整数的运算;对于指向同一连续存储单元的两个指针变量可以进行相减运算;除此之外,不可以对指针变量做任何其他算术运算。

例如:

设在内存中开辟了如图所示的5个连续的、存放整型数据的存储单元,且已经定义了指针变量p和q,并使p指向值为10的存储单元。

执行:

p=p+3;

执行:

q=p-2;

说明:

对指针变量进行加、减一个整数时,数字1并不代表一个字节,而是指向一个存储单元的长度。

至于一个存储单元的长度是多少字节,则视指针变量的基类型而定。

如:

p是int型,则1个单元长度是2个字节;(vc++6.0是4个字节)

p是float型,则1个单元长度是4个字节;

p是double型,则1个单元长度是8个字节;等等。

2.比较运算

两个指针变量间进行比较,实质上就是两个地址间的比较。

如:

p==q;表明两个指针变量指向同一个变量。

通常情况下,只有当两个或多个指针变量指向同一连续存储空间时,指针变量间的比较操作才有意义。

 

6.2指针与函数

指针与函数有三种关系:

①指针可以作为函数参数,②函数的返回值可以是指针,③指针可以指向函数。

一、函数参数为指针变量(P163)

使用指针变量作为函数参数的主要目的之一是:

实现实参与形参按地址传递。

回顾第四章题:

例4.4交换两个变量的值。

问题分析:

原本希望通过调用swap()函数来交换变量x和y的值,但形参a和b的变化并没有影响到实参x和y。

为什么?

#include

usingnamespacestd;

voidswap(inta,intb)

{inttmp;

cout<<"a=”<

tmp=a;a=b;b=tmp;

cout<<"a=”<

}

intmain()

{intx=20,y=-40;

cout<<”x=”<

swap(x,y);

cout<<”x=”<

return0;

}

例6.5利用指针与函数实现两个变量值的交换。

#include

usingnamespacestd;

voidswap(int*a,int*b)

{

inttmp;

cout<<"a=”<<*a<<”,b="<<*b<

tmp=*a;*a=*b;*b=tmp;

cout<<"a=”<<*a<<”,b="<<*b<

}

intmain()

{

intx=20,y=-40;

cout<<"x=”<<*x<<”,y="<<*y<

swap(&x,&y);

cout<<"x=”<<*x<<”,y="<<*y<

return0;

}

问题:

若对例6.5修改为如下程序,分析其运行结果。

#include

usingnamespacestd;

voidswap(int*a,int*b)

{

int*tmp;

cout<<"a=”<<*a<<”,b="<<*b<

tmp=a;a=b;b=tmp;

cout<<"a=”<<*a<<”,b="<<*b<

}

voidmain()

{

intx=20,y=-40;

cout<<"x=”<<*x<<”,y="<<*y<

swap(&x,&y);

cout<<"x=”<<*x<<”,y="<<*y<

}

 

二、函数返回地址值(P177)

函数值的类型既可以简单数据类型,还可以是指针类型。

定义返回指针函数的一般形式:

类型名*函数名(形参表)

{

函数体

}

调用返回指针的函数的赋值语句一般形式:

指针变量=函数名;

表示把函数的地址赋给指针变量,即指针变量指向函数。

案例6.6

#include

usingnamespacestd;

int*fun(int*a,int*b)

{if(*a>*b)returna;

returnb;

}

voidmain()

{

int*p,i,j;

cout<<"entertwonumber:

";

cin>>i>>j;

p=fun(&i,&j);

cout<<"i=”<

}

三、指向函数的指针变量(P175)

1.引入指向函数的指针变量的意义

C++语言规定:

函数名代表该函数的首地址,因此可通过指向该函数的指针变量调用该函数

2.指向函数的指针变量的定义

类型名(*指针变量名)(函数形参表);

例如:

int(*p)(int,int);

表示p为指向返回值为int型函数的指针变量。

例6.7用指向函数的指针调用函数的方法

#include

usingnamespacestd;

intmax(inta,intb)

{

return((a>b)?

a:

b);

}

voidmain()

{int(*p)(int,int);//定义指向函数的指针变量

intx,y,z;

p=max;//p指向函数max

cout<<“pleaseinputa&b:

”;

cin>>a>>b;

z=(*p)(x,y);//等价于:

z=max(x,y);

cout<<“max=”<

}

 

6.3指针与数组

一、一维数组和数组元素的地址关系(P168)

C++规定,数组名代表数组元素的首地址,也即:

是一个指向该数组第一个元素的首地址。

例如:

intst[20];

则:

st+1表示数组元素st[1]的地址,(即st+1的值就是&st[1]);

st+2表示数组元素st[2]的地址,(即st+2的值就是&st[2]);

st+i表示数组元素st[i]的地址,(即st+i的值就是&st[i]);

因此:

*st等价于*(&st[i])也即是:

st[0];

*(st+1)等价于st[1];

*(st+i)等价于st[i];

说明:

①st+i相当于进行st+i*d的运算,

其中d是一个数组元素所占的字节数。

②在引用一维数组第i个元素时有两种方法:

st[i]和*(st+i)

例6.8分别用下标法和指针法访问数组

#include

usingnamespacestd;

voidmain()

{intw[5]={10,20,30,40,50};

inti;

for(i=0;i<5;i++)

cout<

cout<

for(i=0;i<5;i++)

cout<<*(w+i)<<”“;//指针法

cout<

}

二、通过指针变量或带下标的指针变量引用一维数组元素

1.通过指针变量引用一维数组元素

由于数组名代表数组元素的首地址,而计算机为数组分配一片连续的存储单元,因此

通过指针变量利用“间接访问运算符”可达到引用数组元素的目的。

指向数组元素的指针变量定义的一般形式:

类型名*标识符

例如:

intx[10],*p;

p=x;

即:

将数组x的首地址赋给指针变量p,即表示指针变量p指向数组x

则:

p+1等价于x+1,

p+i等价于x+i。

类推:

*p等价于x[0],

*(p+1)等价于x[1],

*(p+i)等价于x[i]。

因此,当一个指针变量p指向数组a的首地址时,访问数组的第i个元素a[i],又有一种的方式:

*(p+i)

例6.9可将上例改为通过指针变量引用一维数组元素

#include

usingnamespacestd;

voidmain()

{intw[5]={10,20,30,40,50},*p=w;

inti;

for(i=0;i<5;i++)

cout<

cout<

for(i=0;i<5;i++)

cout<<*(w+i)<<”“;//地址法

cout<

for(i=0;i<5;i++)

cout<<*(p+i)<<”“;//指针变量法

cout<

}

2.通过带下标的指针变量引用一维数组元素

假设有以下定义语句:

int*p,s[10],i;

p=s;

由于s[i]可以用表达式*(s+1)表示,

则:

*(p+i)也可以用p[i]表示,

即:

通过带下标的指针变量可以引用一维数组元素。

C++规定,当一个指针变量指向一个数组时,这个指针变量在程序中就可以以数组名的身份出现,即可以带下标。

因此,若一个指针变量p指向一个数组a的首地址时,则访问数组的第i个元素a[i],就可以又有一种方式:

p[i]

例6.9将上例改为通过带下标的指针变量引用一维数组元素

#include

usingnamespacestd;

voidmain()

{intw[5]={10,20,30,40,50},*p=w;

inti;

for(i=0;i<5;i++)

cout<

cout<

for(i=0;i<5;i++)

cout<<*(w+i)<<”“;//地址法

cout<

for(i=0;i<5;i++)

cout<<*(p+i)<<”“;//指针变量法

cout<

for(i=0;i<5;i++)

cout<

cout<

}

注意:

在机器内部,对一维数组的访问,实质上就是按*(a+i)的方式访问

三、二维数组和数组元素的地址关系

1、二维数组和数组元素的地址

系统对二维数组的存放是按行顺序进行的。

C++将二维数组的行列下标在定义中用两个括号分开,其目的是:

把二维数组当作一维数组。

例如:

inta[3][4];

其存储形式为:

可看成是:

3个具有4个元素的一维数组。

即:

a[0]-----a[0][0],a[0][1],a[0][2],a[0][3];

a[1]-----a[1][0],a[1][1],a[1][2],a[1][3];

a[2]-----a[2][0],a[2][1],a[2][2],a[2][3];

数组名a表示二维数组的地址,即第0行地址;

a+1表示二维数组第1行地址;

a+2表示二维数组第2行地址;

根据C++规定:

数组名代表数组的地址,

因此:

a[0]代表第0行的首地址:

a[0]+1是第0行第1列元素的地址,

a[0]+j是第0行第j列元素的地址,即&a[0][j]。

a[1]代表第1行的首地址:

a[1]+1是第0行第1列元素的地址,

a[1]+j是第0行第j列元素的地址,即&a[1][j]。

2、通过地址来引用二维数组元素

C++规定,无论a是多少维数组,根据书写形式:

a[0]等价于*(a+0);

a[1]等价于*(a+1);

a[i]等价于*(a+i);

故:

要引用a[i][j],用地址法表示为:

*(a[i]+j),也即是*(*(a+i)+j)

例6.10分析如下程序运行结果

#include

#include

usingnamespacestd;

voidmain()

{inti,j;

inta[3][4]={{1,2,3,4},{10,20,30,40},{100,200,300,400}};

for(i=0;i<3;i++)

cout<

cout<

for(i=0;i<3;i++)

cout<

cout<

for(i=0;i<3;i++)

cout<<*(a+i)<<”“;//每行的首地址

cout<

i=1;

for(j=0;j<4;j++)

cout<

cout<

i=2;

for(j=0;j<4;j++)

cout<<*(a+i)+j<<”“;//第2行各元素的地址

cout<

for(i=0;i<3;i++)

{for(j=0;j<4;j++)

cout<

cout<

}

for(i=0;i<3;i++)

{for(j=0;j<4;j++)

cout<

cout<

}

}

三、通过建立一个行指针来引用二维数组(P179)(*指向由m个元素组成的一维数组的指针变量)

从逻辑上看二维数组是由相同类型的一维数组作为元素而构成的一维数组。

由于内存是一维空间,因此二维数组在内存中的表示是将二维空间上的数据依照某种顺序映射到内存,在C++语言中,是按从上到下、从左到右的次序(行序)来实现这种映射的。

所谓行指针变量就是用来存放“行”地址的变量,即行指针变量是指向一维数组的指针变量,其定义形式如下:

类型名(*指针变量名)[数组长度]

比较如下几个定义:

①intx;定义整型变量x;

②int*px;定义指向整型的指针变量px;

③intb[5];定义含有5个元素的整型数组b;

④int(*p)[5];定义指向含有5个元素的整型数组的指针变量p。

例如:

inta[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};

int(*p)[5];

p=a;

这里p是一个指向含有5个整型元素的一维数组的指针变量;a是一个3行5列的二维数组,即每一行相当于一个含有5个元素的一维数组。

由于二维数组名是一个行指针类型的地址常量,则语句“p=a;”的作用就是将数组首地址赋给p,让行指针变量指向二维数组的a的首行,即一维数组a[0]。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

P,a

P+1

P+2

通过行指针可以表示二维数组的首地址、行地址、元素地址、元素等

当p指向a数组的开头时,可以通过以下形式来引用a[i][j]

*(p[i]+[j])与*(a[i]+[j])相对应

*(*(p+i)+j)与*(*(a+i)+j)相对应

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 笔试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1