c++程序设计谭浩强第6章修订.docx
- 文档编号:27119091
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:40
- 大小:54.30KB
c++程序设计谭浩强第6章修订.docx
《c++程序设计谭浩强第6章修订.docx》由会员分享,可在线阅读,更多相关《c++程序设计谭浩强第6章修订.docx(40页珍藏版)》请在冰豆网上搜索。
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++)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c+ 程序设计 谭浩强第 修订