C语言——二维数组与指针数组&&数组指针&&二级指针

由于个人在写关于字符串数组代码的时候,总会遇到一些关于字符串指针的问题,所以想把这些简单易混的知识点进行梳理

PART 1 二维数组

二维整型数组

int a[m][n]
其中m表示有多少行,n表示有多少列。

int main()
{
    int a[2][2]= {1,2,3,4};
    cout<<a[0]<<endl;     //a[0]是二维数组,第0行的地址。
    cout<<*a[0]<<endl;    //*a[0]是第0行第一个元素
    cout<<*a[0]+1<<endl;  //*a[0]+1是第0行第二个元素
    cout<<*a[0]+2<<endl;  //*a[0]+2是第1行第1个元素,由于数组是线性存放于计算机地址中,所以第三个,也就是(1,1)位置的元素
    cout<<*a[0]+3<<endl;  //*a[0]+3是第1行第2个元素。
}

a[0]
数组的地址,如果你输出a[0],那么你得到只是一段地址。这个就是二维数组的首地址。
*a[0]
这个是a[0]地址的值,输出 * a[0], 结果是1。
*a[0]+1
这个是a[0]地址向后移动1位的位置的值,结果是 2.
*a[0]+2
这个是a[0]地址向后移动2位的位置的值,结果是 3
*a[0]+3
这个是a[0]地址向后移动2位的位置的值,结果是 4
【注释】:由于数组是按照地址线性排列在计算机中的,所以你脑海里的二维情形,只是你脑海中的,a[0]+2这个位置就是我们设计的两行两列数组中第2行第1个元素的位置了。

二维字符数组

char ch[m][n]
二维字符数组,其实是你看到的一维字符串数组。
m表示有多少个字符串,n表示每个字符数可以存放n-1个字符。(因为第n个位置,它要存放‘\0’用来标志字符串的结束)

int main()
{
    char b[3][6]= {"Zhang","Jia","chen"};
    cout<<b<<endl;
    cout<<b+1<<endl;
    cout<<*b<<endl;
    cout<<b[0]<<endl;
    cout<<b[1]<<endl;
    cout<<b[2]<<endl;
}

b
在这里就是字符串数组的首地址,也就是字符串“zhang”的地址
b+1
在这里就是字符串"Jia"的地址
*b
就是取b地址的值,b是数组的首地址,所以 *b就是“Zhang”
b[0]
就是第一个字符串,也就是“Zhang”
b[1]
是第2个字符串,也就是“Jia”
b[2]
是第3个字符串,也就是“chen”

PART 2 指针与字符串数组

二维的数组我们简单介绍完毕,接下来我们介绍关于数组指针和指针数组的事情。
数组指针
int (*p)[n]      p一个指针,指向一维整形数组,这是因为()的优先级高于[ ],所以()先与 *p结合构成指针,指向一维数组。
指针数组
int *p[n]       p是一个数组,“ * ”与数组p[n]结合构成了一个含有n个指向整型元素的指针。
二维指针
int **pp       距离“int”最近的 ‘ * ’告诉我们它是一个指针,它指向的数据类型是 *pp(指针类型)。

假如 :
int a=3;
int *p;(或者int *p=a)
p=&a;(p是一个指针,它的值是地址,*p是p指向地址的值。&a表示a的地址。)
int **pp;
pp=p;(pp得到的是p的“地址”,*pp是p地址的值,p地址的“值”是a的地址,所以 **pp=*p也就是3)

现在我们再详细探讨关于数组指针和指针数组那点小破事

一、指针数组与字符串数组

int main()
{
    char b[3][6]= {"Zhang","Jia","chen"};
    char *p[3];
    //char (*p1)[3];
    *p=b[0];  //*p在这里等价于p[0],指针数组的首地址,指针数组的第一个指针指向了b[0]位置;
    p[1]=b[1];//p[1]这个位置的指针,指向b[1]这个位置
    cout<<*p<<endl;
    cout<<p[0]<<endl;
    cout<<*p+1<<endl; //p指针后移一位的值的第一个元素是h
    //cout<<*(p+1)<<endl;【报错】
    cout<<p[1]<<endl;
}

运行结果:
在这里插入图片描述
*p在这里等价于p[0],指针数组的首地址,指针数组的第一个指针指向了b[0]位置;
p[1]这个位置的指针,指向b[1]这个位置。
同理,你写一个p[2]=b[2];p[2]这个位置的指针,指向b[2]这个位置.
由于这里是指针数组,所以赋值与数组和数组元素赋值一样,要对应的一个一个赋值,不可以直接让p=b,因为这里的指针是存放在数组里面的。p[0]是一个指针,但p不是,p只是这个指针数组的数组首地址而已。
语句 cout<< *(p+1)报错的原因是因为p[1]的指针还没有给他赋值,她没有指向,也就不知道它指向的内容,所以报错
*p+1这个就相当于p指针从p[0]指向位置后移动了一位,所以打印的结果是“hang”

二、数组指针与字符串数组

int main()
{
    //int a[2][2]= {1,2,3,4};
    char b[3][6]= {"Zhang","Jia","chen"};
    char (*p1)[6];//数组指针,指向数组的指针,记住指针指向数组的长度与字符串的长度保持一致
    p1=b;
    cout<<*p1<<endl;
    cout<<p1[0]<<endl;
    cout<<*p1+1<<endl; //p指针后移一位的值的第一个元素是h
    cout<<*(p1+1)<<endl;


}

运行结果:
在这里插入图片描述
p1=b,数组b把首地址的值给了数组指针p1。现在指针p1开始指向数组b.
*p1与p1[0]都是p1在首地址位置的值。
*p1+1是指针p1从当前位置的值,向后移动一位。
*(p1+1)是指针p1挪动一个位置指向数组第二个位置。

三、二级指针与字符串数组

int main()
{
    //int a[2][2]= {1,2,3,4};
    char b[3][6]= {"Zhang","Jia","chen"};
    char *p[6];//指针数组
    char **pp;
    p[0]=b[0];
    p[1]=b[1];
    p[2]=b[2];
    pp=p  ;     //此时pp等于的是p的地址
    cout<<*pp<<endl;
    cout<<*(pp+1)<<endl;
    cout<<*(pp+2)<<endl;


}

运行结果:
在这里插入图片描述
pp等于p意味着pp的值等于p的地址,*pp就是p地址存放的内容,p存放的东西是b的地址,**pp就是在b地址存放的内容。

讲个故事,就好比 b是小偷,只有p知道小偷的位置,pp要找自己找小偷偷的东西,pp知道p的位置,当p带上小“ * ”意味着开始从某地找某物了,*pp模式启动,找到了b的地址,*pp找到了以后,继续开启找东西模式继续带上小 “ * ”,**pp找到了自己丢失的东西。

PART 3 指针与整型数组

最后,再整理一下数组指针,指针数组和二级指针与整型数组的关系
一、指针数组与二维整型数组

int main()
{
    int a[2][2]= {1,2,3,4};
    //char b[3][6]= {"Zhang","Jia","chen"};
    int *p[4];//指针数组
    *p=a[0];
    p[1]=a[0]+1;
    p[2]=a[1];
    p[3]=a[1]+1;
    cout<<*p[0]<<endl;
    cout<<*p[1]<<endl;
    cout<<*p[2]<<endl;
    cout<<*p[3]<<endl;
}

在这里插入图片描述
二、数组指针与二维整型数组

int main()
{
    int a[2][2]= {1,2,3,4};
    //char b[3][6]= {"Zhang","Jia","chen"};
    int (*p)[2];//数组指针
    p=a;
    cout<<*p[0]<<endl;
    cout<<*p[0]+1<<endl;
    cout<<*p[1]<<endl;
    cout<<*p[1]+1<<endl;
}

输出:
在这里插入图片描述数组指针,是指向数组的指针,故只需要把数组的首地址给指针即可。

三、二级指针与二维整型数组

int main()
{
    int a[2][2]= {1,2,3,4};
    //char b[3][6]= {"Zhang","Jia","chen"};
    int *p[4];//指针数组
    p[0]=a[0];//p[0]的指针等于a[0]的地址
    p[1]=a[0]+1;
    p[2]=a[1];
    p[3]=a[1]+1;
    int **pp;
    pp=p;
    cout<<**pp<<endl;
    cout<<**(pp+1)<<endl;//pp+1是p[1]的地址
    cout<<**(pp+2)<<endl;//pp+1是p[2]的地址
    cout<<**(pp+3)<<endl;//pp+1是p[3]的地址
}

输出结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值