64C++数组与指针.docx
- 文档编号:23175131
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:13
- 大小:313.14KB
64C++数组与指针.docx
《64C++数组与指针.docx》由会员分享,可在线阅读,更多相关《64C++数组与指针.docx(13页珍藏版)》请在冰豆网上搜索。
64C++数组与指针
指向数组元素的指针
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。
指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。
所谓数组元素的指针就是数组元素的地址。
inta[10]; //定义一个整型数组a,它有10个元素
int*p; //定义一个基类型为整型的指针变量p
p=&a[0]; //将元素a[0]的地址赋给指针变量p,使p指向a[0]
在C++中,数组名代表数组中第一个元素(即序号为0的元素)的地址。
因此,下面两个语句等价:
p=&a[0];
p=a;
在定义指针变量时可以给它赋初值:
int*p=&a[0]; //p的初值为a[0]的地址
也可以写成
int*p=a; //作用与前一行相同
可以通过指针引用数组元素。
假设p已定义为一个基类型为整型的指针变量,并已将一个整型数组元素的地址赋给了它,使它指向某一个数组元素。
如果有以下赋值语句:
*p=1; //对p当前所指向的数组元素赋予数值1
如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素。
如果p的初值为&a[0],则:
1) p+i和a+i就是a[i]的地址,或者说,它们指向a数组的第i个元素,见图6.12。
图6.12
2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]。
可以看出,[]实际上是变址运算符。
对a[i]的求解过程是:
先按a+i×d计算数组元素的地址,然后找出此地址所指向的单元中的值。
3)指向数组元素的指针变量也可以带下标,如p[i]与*(p+i)等价。
根据以上叙述,引用一个数组元素,可用以下方法:
∙下标法,如a[i]形式;
∙指针法,如*(a+i)或*(p+i)。
其中a是数组名,p是指向数组元素的指针变量。
如果已使p的值为a,则*(p+i)就是a[i]。
可以通过指向数组元素的指针找到所需的元素。
使用指针法能使目标程序质量高。
【例6.5】输出数组中的全部元素。
假设有一个整型数组a,有10个元素。
要输出各元素的值有3种方法:
1)下标法。
1.#include
2.using namespace std;
3.int main( )
4.{
5.int a[10];
6.int i;
7.for(i=0;i<10;i++)
8.cin>>a[i]; //引用数组元素a[i]
9.cout< 10.for(i=0;i<10;i++) 11.cout< 12.cout< 13.return 0; 14.} 运行情况如下: 9876543210↙ (输入10个元素的值) 9876543210 (输出10个元素的值) 2)指针法。 将上面程序第7行和第10行的“a[i]”改为“*(a+i)”,运行情况与 (1)相同。 3)用指针变量指向数组元素。 1.#include 2.using namespace std; 3.int main( ) 4.{ 5.int a[10]; 6.int i,*p=a; //指针变量p指向数组a的首元素a[0] 7.for(i=0;i<10;i++) 8.cin>>*(p+i); //输入a[0]~a[9]共10个元素 9.cout< 10.for(p=a;p<(a+10);p++) 11.cout<<*p<<""; //p先后指向a[0]~a[9] 12.cout< 13.return 0; 14.} 运行情况与前相同。 请仔细分析p值的变化和*p的值。 对3种方法的比较: 方法 (1)和 (2)的执行效率是相同的。 第(3)种方法比方法 (1)、 (2)快。 这种方法能提高执行效率。 用下标法比较直观,能直接知道是第几个元素。 用地址法或指针变量的方法都不太直观,难以很快地判断出当前处理的是哪一个元素。 在用指针变量指向数组元素时要注意: 指针变量p可以指向有效的数组元素,实际上也可以指向数组以后的内存单元。 如果有 inta[10], *p=a; //指针变量p的初值为&a[0] cout<<*(p+10); //要输出a[10]的值 在使用指针变量指向数组元素时,应切实保证指向数组中有效的元素。 指向数组元素的指针的运算比较灵活,务必小心谨慎。 下面举几个例子。 如果先使p指向数组a的首元素(即p=a),则: 1) p++(或p+=1)。 使p指向下一元素,即a[1]。 如果用*p,得到下一个元素a[1]的值。 2)*p++。 由于++和*同优先级,结合方向为自右而左,因此它等价于*(p++)。 作用是: 先得到p指向的变量的值(即*p),然后再使p的值加1。 例6.5(3)程序中最后一个for语句: for(p=a;p cout<<*p; 可以改写为 for(p=a;p cout<<*p++; 3)*(p++)与*(++p)作用不同。 前者是先取*p值,然后使p加1。 后者是先使p加1,再取*p。 若p的初值为a(即&a[0]),输出*(p++)得到a[0]的值,而输出*(++p)则得到a[1]的值。 4)(*p)++表示p所指向的元素值加1,即(a[0])++,如果a[0]=3,则(a[0])++的值为4。 注意: 是元素值加1,而不是指针值加1。 5)如果p当前指向a[i],则 *(p--) 先对p进行“*”运算,得到a[i],再使p减1,p指向a[i-1]。 *(++p) 先使p自加1,再作*运算,得到a[i+1]。 *(--p) 先使p自减1,再作*运算,得到a[i-1]。 将++和--运算符用于指向数组元素的指针变量十分有效,可以使指针变量自动向前或向后移动,指向下一个或上一个数组元素。 例如,想输出a数组100个元素,可以用以下语句: p=a; while(p cout<<*p++; 或 p=a; while(p { cout<<*p; p++; } 在用*p++形式的运算时,很容易弄错,一定要十分小心,弄清楚先取p值还是先使p加1。 用指针变量作函数参数接收数组地址 在前面介绍过可以用数组名作函数的参数。 前面已经多次强调: 数组名代表数组首元素的地址。 用数组名作函数的参数,传递的是数组首元素的地址。 很容易推想: 用指针变量作函数形参,同样可以接收从实参传递来的数组首元素的地址(此时,实参是数组名)。 下面将第5章5.4节中的例5.7程序改写,用指针变量作函数形参。 【例6.6】将10个整数按由小到大的顺序排列。 在例5.7程序的基础上,将形参改为指针变量。 1.#include 2.using namespace std; 3.int main( ) 4.{ 5.void select_sort(int *p,int n); //函数声明 6.int a[10],i; 7.cout<<"entertheoriginlarray: "< 8.for(i=0;i<10;i++) //输入10个数 9.cin>>a[i]; 10.cout< 11.select_sort(a,10); //函数调用,数组名作实参 12.cout<<"thesortedarray: "< 13.for(i=0;i<10;i++) //输出10个已排好序的数 14.cout< 15.cout< 16.return 0; 17.} 18. 19.void select_sort(int *p,int n) //用指针变量作形参 20.{ 21.int i,j,k,t; 22.for(i=0;i 23.{ 24.k=i; 25.for(j=i+1;j 26.if(*(p+j)<*(p+k)) k=j; //用指针法访问数组元素 27.t=*(p+k);*(p+k)=*(p+i);*(p+i)=t; 28.} 29.} 运行情况与例5.7相同。 图6.13 本例与例5.7在程序的表现形式上虽然有不同,但实际上,两个程序在编译以后是完全相同的。 C++编译系统将形参数组名一律作为指针变量来处理。 实际上在函数调用时并不存在一个占有存储空间的形参数组,只有指针变量。 实参与形参的结合,有以下4种形式: 实 参 形 参 数组名 数组名 (如例5.7) 数组名 指针变量 (如例6.6) 指针变量 数组名 指针变量 指针变量 在此基础上,还要说明一个问题: 实参数组名a代表一个固定的地址,或者说是指针型常量,因此要改变a的值是不可能的。 如: a++; //语法错误,a是常量,不能改变 而形参数组名是指针变量,并不是一个固定的地址值。 它的值是可以改变的。 在函数调用开始时,它接收了实参数组首元素的地址,但在函数执行期间,它可以再被赋值。 如: 1.f(array[], int n) 2.{ 3.cout< 4.array=array+3; //指针变量array的值改变了,指向array[3] 5.cout<<*arr< 6.} 多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。 1)多维数组元素的地址 设有一个二维数组a,它有3行4列。 它的定义为: inta[3][4]={{1,3,5,7},{9,11,13,15},{17,18,21,23}}; a是一个数组名。 a数组包含3行,即3个元素: a[0],a[1],a[2]。 而每一元素又是一个一维数组,它包含4图6.14个元素(即4个列元素),例如,a[0]所代表的一维数组又包含4个元素: a[0][0],a[0][1],a[0][2],a[0][3],见图6.14。 可以认为二维数组是“数组的数组”,即数组a是由3个一维数组所组成的。 图6.14 从二维数组的角度来看,a代表二维数组首元素的地址,现在的首元素不是一个整型变量,而是由4个整型元素所组成的一维数组,因此a代表的是首行的起始地址(即第0行的起始地址,&a[0]),a+1代表a[1]行的首地址,即&a[1]。 a[0],a[1],a[2]既然是一维数组名,而C++又规定了数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中0列元素的地址,即&a[0][0]。 a[1]的值是&a[1][0],a[2]的值是&a[2][0]。 图6.15 0行1列元素的地址可以直接写为&a[0][1],也可以用指针法表示。 a[0]为一维数组名,该一维数组中序号为1的元素显然可以用a[0]+1来表示,见图6.16。 欲得到a[0][1]的值,用地址法怎么表示呢? 既然a[0]+1是a[0][1]元素的地址,那么,*(a[0]+1)就是a[0][1]元素的值。 而a[0]又是和*(a+0)无条件等价的,因此也可以用*(*(a+0)+1)表示a[0][1]元素的值。 依此类推,*(a[i]+j)或*(*(a+i)+j)是a[i][j]的值。 图6.16 2)指向多维数组元素的指针变量 ①指向数组元素的指针变量 【例6.7】输出二维数组各元素的值。 这里采用的方法是用基类型为整型的指针变量先后指向各元素,逐个输出它们的值。 1.#include 2.using namespace std; 3.int main( ) 4.{ 5.int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; 6.int *p; //p是基类型为整型的指针变量
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 64 C+ 数组 指针
![提示](https://static.bdocx.com/images/bang_tan.gif)