鱼C论坛

 找回密码
 立即注册
查看: 2082|回复: 6

[已解决]指向指针数组指针的问题

[复制链接]
发表于 2017-11-18 17:13:27 | 显示全部楼层 |阅读模式

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

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

x
初学C语言,遇到一个比较难以搞清的问题,简述如下:
第一段代码:
#include <stdio.h>
int main()
{
        char *pArray[4] = {
                "Aa1!",
                "Bb2",
                "Cc3",
                "Dd4"
        };
        char **p = pArray;
        printf("%s\n",*p);
        printf("%s\n",*(p+1));
        return 0;
}
第二段代码:
#include <stdio.h>
int main()
{
        char *pArray[4] = {
                "Aa1!",
                "Bb2",
                "Cc3",
                "Dd4"
        };
        char *(*p)[4] = &pArray;
        printf("%s\n",**p);
        printf("%s\n",*(*p+1));
        return 0;
}
两段代码输出结果都是一样的。
问题如下,我觉得在使用多级指针赋值时候,左值与右值的类型要保持一致(不知道对不对)
在反复调试过程中我发现pArray的类型是char **,而&pArray 类型是char *(*)[4]
我在复习指针的时候发现有些帖子上认为:“&a的运算结果是一个指针,指针类型是a的类型加*,指针指向类型是a的类型”。链接:http://blog.csdn.net/soonfly/article/details/51131141中第三大部分“三、运算符&和*”。
那么问题来了:
1、为什么在指针数组中&运算结果产生的指针类型不是简单加一个*?
2、是不是第一段代码存在缺陷?似乎没有明确p+1时候应该执行的步长?编译器如何识别出正确的步长呢?
最佳答案
2017-11-19 00:29:57
瓦尔登湖的海水 发表于 2017-11-18 17:48
那么我是否可以这样理解:
在最初char *pArray[4]时,已经为pArray分配了一段内存(分为4'格'),所以在 ...

先来回答前两个问题

1、为什么在指针数组中&运算结果产生的指针类型不是简单加一个*?
char *(*)[4]可以理解为指向char *[4]的指针,如果说简单加一个*号变成char **[4],意义就是有一个4个元素的数组,数组元素的类型是char**

2、是不是第一段代码存在缺陷?似乎没有明确p+1时候应该执行的步长?编译器如何识别出正确的步长呢?
这个所谓的步长,对于char**类型来说,就是sizeof(char*),在程序中没有影响,因为对于pArray数组来说,数组元素的大小也是sizeof(char*)

另外(64位系统)那sizeof(pArray) = 32,sizeof(*pArray) = 8这里的8是怎么出来的呢?
这个sizeof(*pArray)等同于sizeof(pArray[0])也就是sizeof(char*),在64位程序里为8也就不难理解了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-18 17:19:49 From FishC Mobile | 显示全部楼层

回帖奖励 +10 鱼币

指针数组在初始化的时候会在内存分配的时候确定具体长度,所以&操作会受到前面实际内存分配的影响。也正因为如此,执行p+1操作能够正确偏移
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-18 17:48:52 | 显示全部楼层
BngThea 发表于 2017-11-18 17:19
指针数组在初始化的时候会在内存分配的时候确定具体长度,所以&操作会受到前面实际内存分配的影响。也正因 ...

那么我是否可以这样理解:
在最初char *pArray[4]时,已经为pArray分配了一段内存(分为4'格'),所以在**p=pArray时p已经确定了+1时候步长?
那&操作符在取pArray地址时为什么把结果指针类型变成了char *(*)[4]?
另外(64位系统)那sizeof(pArray) = 32,sizeof(*pArray) = 8这里的8是怎么出来的呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-18 21:06:31 | 显示全部楼层

回帖奖励 +10 鱼币

指针的步长 是由 变量类型决定的。
一个 char* 指针 +1 步长就是  sizeof(char); 其他类型类推。
又比如:
typedef struct _abc{
char a,b,c,d;
}tadc;

tabc* 指针的步长就是 sizeof(tadc)。 如果你将指针强制变成 char*  那么要跳下一个元素时 就要 + sizeof(tadc)  而不是 +1.

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

使用道具 举报

发表于 2017-11-19 00:29:57 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +10 鱼币

瓦尔登湖的海水 发表于 2017-11-18 17:48
那么我是否可以这样理解:
在最初char *pArray[4]时,已经为pArray分配了一段内存(分为4'格'),所以在 ...

先来回答前两个问题

1、为什么在指针数组中&运算结果产生的指针类型不是简单加一个*?
char *(*)[4]可以理解为指向char *[4]的指针,如果说简单加一个*号变成char **[4],意义就是有一个4个元素的数组,数组元素的类型是char**

2、是不是第一段代码存在缺陷?似乎没有明确p+1时候应该执行的步长?编译器如何识别出正确的步长呢?
这个所谓的步长,对于char**类型来说,就是sizeof(char*),在程序中没有影响,因为对于pArray数组来说,数组元素的大小也是sizeof(char*)

另外(64位系统)那sizeof(pArray) = 32,sizeof(*pArray) = 8这里的8是怎么出来的呢?
这个sizeof(*pArray)等同于sizeof(pArray[0])也就是sizeof(char*),在64位程序里为8也就不难理解了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-19 18:09:52 | 显示全部楼层

回帖奖励 +10 鱼币

不知道啥意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-27 14:37:53 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 10:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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