指针和数组

来源:互联网 发布:全景天窗 知乎 编辑:程序博客网 时间: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]; //也可以这样写 





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 招行ubank不对账怎么办 信贷公司利息高不合理怎么办 衣服上的logo掉怎么办 ui设计师接不到私活怎么办 微信打开很慢怎么办 小泰迪感冒加身上结痂怎么办 法斗眼睛肿了怎么办 地图鱼身上有白点怎么办 人被广告牌砸了怎么办 小米手机出现繁体中文英文怎么办 雅思考试把姓名写错了怎么办 房贷的流水账假怎么办 报到证报道期限过期了怎么办 注销公司公章丢了怎么办 家里的猫太调皮怎么办 孩子纹身了我该怎么办 46天婴儿感冒了怎么办 狗病了不吃东西怎么办 幼儿急诊见风了怎么办 哺乳期乳房有硬块而且疼怎么办 哺乳期乳头破裂乳房似针扎怎么办 回奶胀痛的厉害怎么办 淡水龟的壳变软了怎么办 棕色的泰迪变白怎么办 大班教案泥石流来了怎么办 鸟类的嘴巴坏了怎么办 四川麦蚊子咬了怎么办 脸上被晒脱皮了怎么办 额头被晒脱皮了怎么办 脸黑一块白一块怎么办 小乌龟的壳软了怎么办 把田螺后面吃了怎么办 微生物生态菌群异常怎么办 怀孕初期感染了动物病毒怎么办? 金龙和银龙打架怎么办 海水缸盐度高了怎么办 洗空调洗坏了怎么办 老师是条青花鱼怎么办 吃了带鱼和南瓜怎么办 苹果平板ad忘了怎么办 小米6进海水了怎么办