指针数组与数组指针

目录

指针数组:

①一维数组的赋值:对数组中的某一个元素进行取地址

②在存放一个二维数组的每行首地址时,整型数组和字符数组都可以这样赋值:

数组指针:

①一维数组的赋值:需要对整个一维数组进行取地址

②二维数组的赋值:类比一维数组,是需要对一整个 “一维数组” 取地址的,

事实上,用一个普通的指针,也有类似与数组指针的效果:

*p++与*(p++)与(*p)++

小结:用指针对二维数组a[i][j]的引用:

①:数组指针

②:二级指针(感觉有点绕

③:动态分配

​编辑

④:最普通的指针(元素指针

Demo:



指针数组:

①一维数组的赋值:对数组中的某一个元素进行取地址

int *p[5];
for(int i=0;i<n;++i) p[i]=a+i  //或者&a[i]

②在存放一个二维数组的每行首地址时,整型数组和字符数组都可以这样赋值:

每一行取首地址,即取元素words[i][0]的地址;

 而字符数组可以直接通过每行的首地址输出内容:

但是整型数组不可以,这样只会输出它的首地址,想要输出内容必须加*

数组指针:

①一维数组的赋值:需要对整个一维数组进行取地址

int (*p)[5],a[5];
p=&a;

 有个很有趣的现象:

 从输出值来看,a=*(&a)=*p  =  &a=p

但事实上,前三者表示a[0]的地址,后两者表示数组a的(首)地址

tip:如果a为char数组,就只能写成p=a;//a本来就代表整个数组地址了

以及:*a=a[0];

②二维数组的赋值:类比一维数组,是需要对一整个 “一维数组” 取地址的,

而不能写成p=a[i],因为a[i]是单个元素a[i][0]的地址

int (*p)[3],a[5][3];

  p=a  //即&a[0]

cout<<(*p)[1]; //*(a[0]+1)=a[0][1]

那么问题来了,此时的*p[2]是什么?

*p[2]=*(*(p+2))=*(a[2])=a[2][0]

另外,与一维数组类似,p与*p的输出值相同(即:*(p+i)=p[i]=p+i   )

事实上,用一个普通的指针,也有类似与数组指针的效果:
 

一维数组:

int a[5],*p;
p=a;
for(int i=0;i<5;++i)
 p[i]=i;

//p+i===>a+i
//p[i]===>*(p+i)===>*(a+i)==>a[i]

for(;p<a+5;++p)
 cout<<*p;  //输出数组a的所有值

*p++与*(p++)与(*p)++

*和++都是从右到左结合的

因此*p++等同于*(p++)

即输出指针p原来指向位置的值,且p指向的下一个位置

详细见:http://t.csdn.cn/gPaBc

j二维数组:

int b[3][4],*p1,*p2;
p1=b[0]+1;  //b[0]=*b=&b[0][0]  b[0]+1=&b[0][1]
p2=*(b+2)+2;  //*(b+2)=&b[2][0]  *(b+2)+2=&b[2][2]

小结:用指针对二维数组a[i][j]的引用:

①:数组指针

int (*p)[j]; //(注意是j不是i)
p=a;  //二维数组第一行的行地址
//a[i][j]=*(p+i)[j]

②:二级指针(感觉有点绕

int *p1[i],**p2=p1;//不能有&:因为一个二级指针指的是 “一个” 一级指针的地址
//&p1就是对这 “整个数组” 取了地址
//所以事实上也不用定义**p2,因为p1本身就是数组p1[i]的地址

for(int j=0;j<i;++j) p1[j]=a[j];
//a[i][j]=p1[i][j]=p2[i][j];

③:动态分配

int **p=new int *[i];
for(int m=0;m<i;++m) p[m]=new int[j];
//a[i][j]=p[i][j]

for(int m=0;m<i;++m) delete[] p[m];
delete[] p;//顺序不可以翻掉!!!!!!!!!!

④:最普通的指针(元素指针

int *p=a[0]//&a[0][0]

//p可通过一系列的++,依次表示地址
//a[i][j]=*(p+i*列数(每行多少列)+j) 这样就是说a[i][j]的值不方便看

Demo:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    typedef int(*array5)[5];
    int a[5] = {1, 2, 3, 4, 5};
    array5 ar = &a;  // 相当于int (*ar)[5]=a,(*ar)[i]是一个int,即输出int的格式为(*ar)[i]
    int(*p)[5] = &a; //(*p)[i]是一个int,即输出int的格式为(*p)[i]
    int *o = a;      //*o是一个int,即输出int的格式为*o
    int *aa[5];      // 指针数组,存放一系列的指针,所以只能对指针们挨个赋值。*aa[5]是一个int
    for (int i = 0; i < 5; ++i)
        aa[i] = a + i;
    cout << (*ar)[0] << endl; // 1
    cout << (*p)[1] << endl;  // 2
    cout << o[2] << endl;     // 3
    cout << *aa[3] << endl;   // 4

    int b[5][5] = {1, 2, 3, 4, 5};
    array5 at = b;            // 相当于 int (*at)[5]=b
    cout << (*at)[0] << endl; // b[0][0]
    int(*r)[5] = b;
    //(*r)[i]是一个int,即输出int的格式为(*r)[i]  而(*(r+k))[i]相当于先对r进行整体的偏移,即偏离i*k个单位
    cout << r[0][1] << endl;    // b[0][1]
    cout << *(*(r + 2)) << endl;  // b[2][0]
    int *e[5];                  // 指针数组,存放一系列的指针,所以只能对指针们挨个赋值。*e[i]是一个int
    for (int i = 0; i < 5; ++i) //每一个指针指向每个一维数组的首地址
        e[i] = b[i];
    cout << e[0][2] << endl; // b[0][2]
    cout << *e[3] << endl;   // b[3][0]
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值