鱼C论坛

 找回密码
 立即注册
查看: 2487|回复: 8

[已解决]S1E23:指针数组和数组指针

[复制链接]
发表于 2022-2-9 02:38:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
aaaaaaa图片1.png 这个代码里的 bbbbb图片1.png 这一句代码表示的是数组指针的指针还是字符指针类型的数组指针啊?如果是字符指针类型想不通的是这个字符指针对应的是数组指针还是上一行代码 ccccc图片1.png 中的指针数组元素里的字符串呢? 麻烦大神解答解答!!!@
最佳答案
2022-2-9 13:11:01
本帖最后由 番杰 于 2022-2-9 13:12 编辑

(1)char  *(*p)[5]  首先看括号里的:*p,所以p是一个指针,
它指向的是一个char *[5],即指针数组;
这个指针数组里有5个指向char类型的指针。
所以,p是一个指向指针数组的指针。

另:char(*)[5]这个才是数组指针,即指向一个内含5个指向char类型的指针。
所以指向数组指针的指针应该这样写:char  (*(*p))[5];

(2)至于char  *array[5],你理解了第一个问题的话,就好解释多了;
可以看出array是一个数组,一个含有5个char * (即指向char的指针)的数组;

所以它实际存储的并不是一个字符串,而是这个字符串的起始地址;

举个例子:
“FishC”这个字符串的起始地址是:0;(这里的地址只是随便写的,正常地址的长度应该是int类型)
“Fiive”这个字符串的起始地址是:20;
“Start”这个字符串的起始地址是:56;
“Good”这个字符串的起始地址是:88;
“WoW”这个字符串的起始地址是:96;
所以,存储在数组array中的数据则是:[0,20,56,88,96],然后再通过指针去访问字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-9 13:11:01 | 显示全部楼层    本楼为最佳答案   
本帖最后由 番杰 于 2022-2-9 13:12 编辑

(1)char  *(*p)[5]  首先看括号里的:*p,所以p是一个指针,
它指向的是一个char *[5],即指针数组;
这个指针数组里有5个指向char类型的指针。
所以,p是一个指向指针数组的指针。

另:char(*)[5]这个才是数组指针,即指向一个内含5个指向char类型的指针。
所以指向数组指针的指针应该这样写:char  (*(*p))[5];

(2)至于char  *array[5],你理解了第一个问题的话,就好解释多了;
可以看出array是一个数组,一个含有5个char * (即指向char的指针)的数组;

所以它实际存储的并不是一个字符串,而是这个字符串的起始地址;

举个例子:
“FishC”这个字符串的起始地址是:0;(这里的地址只是随便写的,正常地址的长度应该是int类型)
“Fiive”这个字符串的起始地址是:20;
“Start”这个字符串的起始地址是:56;
“Good”这个字符串的起始地址是:88;
“WoW”这个字符串的起始地址是:96;
所以,存储在数组array中的数据则是:[0,20,56,88,96],然后再通过指针去访问字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-2-10 12:23:07 | 显示全部楼层
番杰 发表于 2022-2-9 13:11
(1)char  *(*p)[5]  首先看括号里的:*p,所以p是一个指针,
它指向的是一个char *[5],即指针数组;
...

这个&array取出的是        数组体(整个array数组存放的地址)
那么在 将&array这个地址赋值给 char*(*p)[5] 这个数组指针的指针的时候是将&array地址赋值给(*p)[5]然后再定义为char*类型 还是 将&array直接赋值给*(*p)[5] (即整个数组指针地址的地址)里呢?对于&array赋值给数组指针我是弄懂了 就是没太懂数组指针的指针这个概念 请指教。 aaaaa图啊啊啊啊片1.png cccccc图片1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-10 13:07:58 | 显示全部楼层
首先&array的数值是数组array的起始地址,而不是整个array数组存放的地址;
而且&array的数据类型是一个数组指针,就是一个指向数组array的指针,注意它的数据类型的本质是一个指针。

其次,先定义在赋值,先定义char*(*p)[5] ,然后在把&array的值赋值给p;
之前也说过了,p的数据类型是一个指向数组的指针;
而&array的数据类型也是一个数组的指针;
同时二者指向的数组都是:一个指针数组,即char *[5]类型的。
所以二者可以进行赋值操作。

另外,数组指针和指针数组的本质区别也很简单:一个是指针,一个数组。
1)数组指针:它是一个指针,它指向的是一个数组。
即像这样:char (*p)[5]
这里的p就是一个指向char [5]的数组的指针。

2)指针数组:它是一个数组,数组内的元素是多个指针。
即像这样:char *p[5]
这里的p就是一个包含5个指向char指针的数组。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-2-10 23:18:06 | 显示全部楼层
番杰 发表于 2022-2-10 13:07
首先&array的数值是数组array的起始地址,而不是整个array数组存放的地址;
而且&array的数据类型是一个数 ...

Q1.
aaaaaa图片1.png
Array(数组名)就是这个数组的起始地址 那为什么&array还是起始地址呢;
刚才想了一下 &array是array数组的起始地址
而 array和&array[0]一样 是数组首元素的地址
是这个意思嘛?

Q2.
bbbbbb图片1.png
这个含义我知道 只是不理解的是:char*(*p)[5]不是数组指针的指针吗 那在赋值&array时在(*p)[5]前面还有一个* 没有理解这个*号是啥意思 思来想去 觉得定义一个char(*p)[5]就行了不知道为什么要是char*(*p)[5]  QAQ

Q3.
ccccccc图片1.png
想请教一下大神我这么想对不对:
P为指针数组的数组起始地址
*p为首个元素的起始地址
*(*p + i)为第i个元素内存放的值(即某字符串首地址)
*(*(*p + i) + j))为第i个字符串首地址里的第j个字符
这么理解对吗?

Q4.
ddddddd图片1.png
这里为什么要用指针数组呢 不是想的太清晰 猜想是将字符串都变成指针?后期好调用吗?

感谢大神的耐心教导!@
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-11 10:23:40 | 显示全部楼层
本帖最后由 番杰 于 2022-2-11 10:29 编辑
youxixingzhet 发表于 2022-2-10 23:18
Q1.

Array(数组名)就是这个数组的起始地址 那为什么&array还是起始地址呢;


A1.array和&array[0]没错,都是数组array的起始地址;
&array的数值也是数组array的起始地址,也没错,但是注意是数值!数值!
我之前也说了:&array的数据类型是一个指向array的数组指针,它是一个指针,
而array数组本身定义的就是一个指针数组,所以&array就变成了一个指向指针数组的指针了,
所以它的数据类型就是:char *(*)[5]。
而array和&array[0]的数据类型是数组,就是你定义array的char * [5](指针数组);
所以&array在本质上是和前面两个不同的。

A2.这里面的第二个*,就是跟p在一个括号里的那个,它是来修饰p的,表明p是一个指针;
而剩下的其余的符号都是代表这个p指向的数据类型,直接去掉(*p)看:
定义中剩下的就是:char *[5],这就表明p是指向这个数据类型(指针数组)的指针;
所以p就是一个指向指针数组的指针,
所以p的数据类型就是:char*(*)[5];
前面A1里也说了,&array的数据类型也是char*(*)[5];
所以二者才可以进行赋值操作。
所以换成char(*p)[5]是不行的,换成array也是不行的。

A3.完全正确!!
我个人觉得换成语法糖的形式会更好理解一些,
语法糖的帖子请戳这里:什么是语法糖

A4.这里并不是把字符串变成了指针,而是用指针指向字符串,
就像我最开始的时候说的array数组里存放的并不是字符串,
而是指向字符串的指针;
说白了就是字符串的地址。

然后通过解引用就是能读出字符串中的字符。
方法就是A3那样,两次解引用。
第一次解引用是选哪个字符串;
第二次解引用是选哪个字符。

你用语法糖会更好理解的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-2-12 00:32:15 | 显示全部楼层
番杰 发表于 2022-2-11 10:23
A1.array和&array[0]没错,都是数组array的起始地址;
&array的数值也是数组array的起始地址,也没错 ...

title看见杰哥A3里面那两个感叹号我整个人都燃了

Q1.
针对杰哥的answer1作出自我理解:
①那个定义数组指针里   char* 是给&array这个array数组起始地址最底层数据作为数据类型所定义的。
②你说的“&array的数值也是数组array的起始地址,也没错,但是注意是数值!数值!”
你看我理解的对不对哈:&array实际上是array这个数组在内存里的起始地址 只不过单独看&array时 称作为数值 ;对于(&array的数值也是数组array的起始地址)这一句话请问意思是&array这个数值是array这个数组元素的首地址 还是我上面理解的&array是array数组在内存里的起始地址呢?

Q2.
针对杰哥的A2我理解了一下:
Char *(*p)[5]中*p是指针 剩下 char*[5]是字符型指针数组 对于p而言是指向字符型指针数组的指针。!!那整体看 char *(*p)[5] 这句话他不是数组指针吗?(总感觉哪里不太对)

Q3.
新问题(一次性问完  嘿嘿嘿!~)
①字符型数组里面的元素是不是不可以存放一个字符串 如要数组里要想存放字符串就只能一个元素一个字符这个读写啊?

②指针数组就是为了让字符串存放在元素里更方便的调用吗?????如果不对可以给我简单讲讲它的优势嘛~

③数组指针 对于它我就。。脑子一片空白(杰哥给讲讲呗)

④杰哥别慌 最后一个  !!奥利给 !!
中文存放数组里 假设一个汉字是三个字节 在char数组里一个元素存放三个字节中一个ascii值 那等我读取这个数组的汉字时  编译器知道 哪几个字节是一起进来的不???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-1 11:56:04 | 显示全部楼层
youxixingzhet 发表于 2022-2-12 00:32
title看见杰哥A3里面那两个感叹号我整个人都燃了

Q1.

不好意思,前段时间出差了,才回来,下面一起看看问题:

A1.
①怎么说好呢,我觉得你应该是已经理解了这的意思,但是表述吧,有点复杂吧(?我也不太确定是不是准确)应该不是“起始地址最底层数据”,char*就是表示了数组存储的数据类型,即字符型指针。所以在数组array中实际存储的就是这个字符型指针指向数据的地址。(换句话说,array中存储的就是另一个内存的地址)。
②不能单独的从数值上看&array!我举个简单的例子:
int a = 5;
float b = 5.0;
如果你单独从数值上看,a和b的数值大小都是5;
但你要是不去考虑它俩的数据类型的话,那就会出大问题:
例:a/2 = 5/2 = 2;
b/2 = 5.0/2 = 2.5;
虽然a和b的数值大小都是5,但同样的算式得到的结果是不同的,
所以不能单独从数值上看,必须结合其数据类型一起看。

回到这个问题上:对于“&array的数值也是数组array的起始地址”这一句话的意思。
你后面说的对,就是&array这个数值是array这个数组元素的首地址,但你在使用它的时候要考虑到它的数据类型。

A2.
整体看 char *(*p)[5]的话,p确实是一个数组指针;
只不过这里面的数组前面有一个修饰,即字符型指针数组,
这里面的字符型指针是用来修饰数组的,而非修饰p的,
所以本质上,p就是一个数组指针。

A3.
①字符型数组的字符读写确实是一个元素一个字符这样的;
但是你用一个循环,就可以一次性完成读或写。
这里的“一次性”是指一个循环执行多次完成,完成后退出循环。
字符串是以‘\0’结尾的,所以就可以用它当做判断条件。

②指针数组的就是可以吧其他地址上的数据读出来,他们可以是非连续的。
比如:char *a[3] = {"asd","zxc"."qwe"}
这里面
“asd”的起始地址假设是1,
“zxc”的起始地址假设是15,
“qwe”的起始地址假设是50,

这就做到了把3个不同地址的数据连到一起(“连到一起”这个表述可能不是太准确,但是就是这个意思)
算是跟好的利用了内存。

③数组指针跟指针的用法都是一样的,只不过就是他指向的是一个数组(起始地址)。

④这个是跟你有点编译器有关,三个字符构成一个汉字的我还真没用过,我用的都是2个字符代表一个汉字,
我以两个字符的举例,三个的应该差不多:
就比如你输入“你好”,在电脑看你输入的就是:
x1(“你”字的前半段的数值) x2(“你”字的后半段的数值)        x1x2一起构成“你”字
y1(“好”字的前半段的数值) y2(“好”字的后半段的数值)        y1y2一起构成“好”字
那几个字节是一起的这个是会强制对齐的,(这是需要看编译器的)
就好比x1一定是在偶地址上,x2一定就在奇地址上。
电脑就把这一对奇偶地址看成一个字符。

举例:
x1地址是2,x2地址是3,y1地址是4,y2地址是5,
那么读出的就是“你好”

若x1地址是1,x2地址是2,y1地址是3,y2地址是4,
那么读出的x2与y1的结合汉字,y2和地址5上数值的结合汉字
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-1 15:25:03 | 显示全部楼层
番杰 发表于 2022-3-1 11:56
不好意思,前段时间出差了,才回来,下面一起看看问题:

A1.

辛苦 杰哥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-16 21:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表