指针和数组
来源:互联网 发布:全景天窗 知乎 编辑:程序博客网 时间:2024/06/05 03:02
一、指针与数组的关系
指向数组的指针变量称为数组指针变量。一个数组是一块连续的内存单元组成的,数组名就是这块连续内存单元的首地址。一个数组元素的首地址就是指它所占有的几个内存单元的首地址。一个指针变量即可以指向一个数组,也可以指向一个数组元素,可把数组名或第一个元素的地址赋予它。如要使指针变量指向第 i 号元素,可以把 i 元素的首地址赋予它,或把数组名加 i 赋予它。
设有数组 a,指向 a 的指针变量为 pa,则有以下关系:pa、a、&a[0]均指向同一单元,是数组 a 的首地址,也是 0 号元素a[0]的首地址。pa+1、a+1、&a[1]均指向 1 号元素 a[1]。类推可知 pa+i、a+i、&a[i]指向 i 号元素 a[i]。pa 是变量,而 a,&a[i]是常量,在编程时应予以注意。
二、指向数组的指针
数组指针变量说明的一般形式为:
类型说明符 *指针变量名
其中类型说明符表示所指数组的类型,从一般形式可以看出,指向数组的指针变量和指向普通变量的指针变量的说明是相同的。
引入指针变量后,就可以用两种方法访问数组元素了。
例如定义了 int a[5];int *pa=a;
第一种方法为下标法,即用 pa[i]形式访问 a 的数组元素。
第二种方法为指针法,即采用*(pa+i)形式,用间接访问的方法来访问数组元素。
【例 5】scanf 使用数组名,用数组名或指针访问数组。
#include<cstdio>using namespace std;int main(){int a[5],i,*pa=a;//定义整型数组和指针for(i=0;i<5;i++){//scanf("%d",a+i);//可写成pa+i和&a[i] //scanf("%d",pa+i);scanf("%d",&a[i]);} for(i=0;i<5;i++){//printf("a[%d]=%d\n",i,*(a+i));//指针访问数组,可写成*(pa+i)或pa[i]或a[i] //printf("a[%d]=%d\n",i,*(pa+i));//指针法//printf("a[%d]=%d\n",i,pa[i]);//下标法printf("a[%d]=%d\n",i,a[i]);}return 0;}
【说明】
①、直接拿 a 当指针用,a 指向数组的开始元素,a+i 是指向数组的第 i 个元素的指针。
②、指针变量 pa 是变量,可以变的。但数组 a 是静态的变量名,不可变,只能当做常量指针使用。例如:p=p+2;是合法的,a=a+2;是非法的。
③、最早在使用标准输入 scanf 时就使用了指针技术,读入一个变量时要加取地址运算符’&’传递给 scanf 一个指针。对于数组,可以直接用数组名当指针。
三、指针也可以看成数组名
指针可以动态申请空间,如果一次申请多个变量空间,系统给的地址是连续的,就可以当成数组使用,这就是传说中的动态数组的一种。
【例 6】动态数组,计算前缀和数组。
b 是数组 a 的前缀和的数组定义: b[i]=a[1]+a[2] +…+a[i],即 b[i]是 a 的 i 个元素的和。
#include<iostream>using namespace std;int n;int *a;//定义指针变量a,后面直接当数组名使用 int main(){scanf("%d",&n);a=new int[n+1];//向操作系统申请了连续的n+1个int型的空间 for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=2;i<=n;i++){a[i]+=a[i-1];}for(int i=1;i<=n;i++){printf("%d ",a[i]);}return 0;}
【说明】
动态数组的优点:在 OI 中,对于大数据可能超空间的情况是比较纠结的事,用小数组只的部分分,大数组可能爆空间(得 0 分)。使用“动态数组”,可以在确保小数据没问题的前提下,尽量满足大数据的需求。
行列转换问题
【问题描述】
矩阵可以认为是N*M的二维数组。现在有一个巨大但稀疏的矩阵。
N,M的范围是:1<=N ,M <=100000,有k个位置有数据,K的范围是:1<=K<=100000.
矩阵输入的方式是从上到下(第1行到第N行)、从左到右(从第一列到第M列)扫描,记录有数据坐标的位置(x,y)和值(v)。这是按照行优先的顺序保存数据的。现在要求按照列优先的方式输出数据,即从左到右、从上到下扫描,输出有数据的坐标和数值。
【输入格式】
第1行,3个整数N,M,K,其中1<=N,M,K<=100000;下面有K行,每行3个整数;a,b,c,表示第a行第b列有数据c。数据在int范围内,保证是行优先的次序。
【输出格式】
1行,K个整数,是按照列优先次序输出的数
【样例输入】
4 5 9
1 2 12
1 4 23
2 2 56
2 5 78
3 2 100
3 4 56
4 1 73
4 3 34
4 5 55
【样例输出】
73 12 56 100 34 23 56 78 55
【样例解释】
#include<cstdio>using namespace std;const int LP=100001;int n,m,k;int x[LP],y[LP],d[LP];int c[LP];int *a[LP];int main(){scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=k;i++){scanf("%d%d%d",&x[i],&y[i],&d[i]);//x[i],y[i]是第i个数据所在的行号和列号 c[y[i]]++;//统计c数组中每列数据的个数 }for(int i=1;i<=m;i++){a[i]=new int[c[i]];//第i列指针申请c[i]个空间 } for(int i=1;i<=k;i++)//收集k个数据到相应的列中 {*a[y[i]]=d[i];//数组放在相应的列数组中//a[y[i]][0]=d[i]; //也可以这样写 a[y[i]]++;//数组指针移到下一个位置 }for(int i=1;i<=m;i++)//列优先 {a[i]-=c[i];//指针回到每列的前面 for(int j=1;j<=c[i];j++,a[i]++){printf("%d ",*a[i]);}}return 0;}
【说明】可以把指针当数组名用,即
*a[y[i]]=d[i];//数组放在相应的列数组中a[y[i]][0]=d[i]; //也可以这样写
- 指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- 数组指针和指针数组
- 指针数组和数组指针
- 指针数组和数组指针
- 数组指针和指针数组
- android集成第三方微信登录
- Java中的文件上传
- 专一、自动化代码生成探讨
- 如何快速搭建一个微服务架构?
- 技术分享的好处
- 指针和数组
- reboot流程分析
- 用户管理(二):使用shell脚本批量删除除root用户以外的其它用户
- Java中的lamda表达式---更加高效简洁的表达方式
- 实训第一章
- Mybatis整合spring
- 手游服务端框架之客户端协议组合下发
- Java实训课1
- webkit与Chrome