鱼C论坛

 找回密码
 立即注册
查看: 2752|回复: 2

数组指针和指针数组不太理解

[复制链接]
发表于 2017-12-16 22:55:44 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Hermione 于 2017-12-16 23:33 编辑

1.
#include <stdio.h>

int main()
{
        int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int *p = (int *)(&array + 1);

        printf("%d\n", *(p - 6));

        return 0;
}

我不明白第5行,强制转换(int *),我觉得不需要转换,因为&array + 1已经代表一个地址了啊

2.
#include <stdio.h>

int main()
{
        int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int (*p)[10] = &array;

        printf("%d\n", *(*(p+1)-6));

        return 0;
}
     
不明白第8行,我是这样想的:p+1代表一个地址,也就是array结束后的第一个地址,那么为什么还要在p+1外面加层*,这样就是去那个地址的内容了啊

我输出*(p + 1)和(p + 1),没差别,但是我输出*(*(p+1) - 6)和*((p+1)-6),差别就大了去了,实在不能理解

3.
#include <stdio.h>

int main()
{
        char *p1[5] = {
                "让编程改变世界 -- 鱼C工作室",
                "Just do it -- NIKE",
                "一切皆有可能 -- 李宁",
                "永不止步 -- 安踏",
                "One more thing... -- 苹果"
        };
        int i;

        for (i = 0; i < 5; i++)
        {
                printf("%s\n", p1[i]);
        }

        return 0;
}

[fishc@localhost s1e23]$ gcc test3.c && ./a.out

这段代码,char *p1[5],这是一个数组,元素是指向字符类型的指针,那么,相当于*p1[0] = "让编程改变世界……",那么相当于它里面是后面这个数组的第一个位置,但是我用
char *p = "鱼C";
printf("%s", *p);
就出毛病了,停止工作什么的

P.S.谢谢大家帮助,本人大一学生,感觉程序设计基础要挂,赶紧突击一下的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-12-17 10:11:32 | 显示全部楼层
我来自己回答一下自己吧
1.&array + 1这时候的跨度是array级别的,也就是10(不考虑int的4,因为没必要),那么&array + 1这个地址是array相邻的一大块地址,通过int *,强行降低维度,那么代表的跨度又是1了,往前数6当然就是4
2.p+1的确是代表一个地址,但是它代表的跨度是10,指向的在array数组前面好多,早已越界
如果p的跨度不为1,那么*p就是在降低跨度
3.输出*(p+z)和(p+1)相等不奇怪,因为这时候都是指向一块地的第一个位置,但是它们跨度不同,所以*(*(p+1)6)和*((p+1)-6)是不一样的

我这样理解肯定跟真实情况有出入,这是为了我理解上容易,欢迎大家的补充
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-17 10:14:21 | 显示全部楼层
第一个问题:
   是一定需要强制转化,因为&array+1是表示一个地址,但是这个地址一定就是指向int类型的数据么,并不是,有时可能
是struct,也有可能是一个类class,所有编译器需要在赋值时给出强制转化,至于转化后的结果是否能被访问,那就是程序
崩溃的问题了。

第二个问题:
   int (*p)[10] = &array;相当于*p = array; p = &array;
   如:p = 0x00400000 , 那么p+1的结果为:0x00400000 + 40; 这个40表示的是当前有10个大小4的元素,所以要跳过。
   那么*(p+1)指向的地址就应该是[0x00400040],也就是array[10]这个元素(虽然它并不存在,但在内存里它是存在的)
   *(p+1) - 6 , 就相当于array + 10  - 6;
   *(*(p+1) - 6),就相当于array[10 -6] = array[4],所以输出的结果为4。
   *(*(p+1)-6) 与 *((p+1)-6)的区别:p+1-6 相当于:0x0040000 - 5 * 40 ;这个地址明显是有问题的。

第三个问题:
  printf("%s", *p);
  printf的第二个参数是一个char *,直接传p就行,而*p表示字符数组的第一个元素。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-29 01:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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