鱼C论坛

 找回密码
 立即注册
查看: 1429|回复: 4

[已解决]指针与二维数组

[复制链接]
发表于 2021-9-30 13:29:12 | 显示全部楼层 |阅读模式
1鱼币
大佬们,两个问题
第一个问题:
数组指针里存放的应该是数组的地址,但是指向二维数组时数组名不需要加&符号,这是为什么?
#include <stdio.h>

int main()
{
        int array[2][3] = {{0, 1, 2}, {3, 4, 5}};
        [b]int (*p)[3] = array;[/b]

        printf("**(p+1): %d\n", **(p+1));
        printf("**(array+1): %d\n", **(array+1));
        printf("array[1][0]: %d\n", array[1][0]);
        printf("*(*(p+1)+2): %d\n", *(*(p+1)+2));
        printf("*(*(array+1)+2): %d\n", *(*(array+1)+2));
        printf("array[1][2]: %d\n", array[1][2]);

        return 0;
}
第二个问题:
第23课作业做一做第一题代码:
#include <stdio.h>

int main()
{
        char *array[5] = {"FishC", "Five", "Star", "Good", "WoW"};
        char *(*p)[5] = &array;
        int i, j;

        for (i = 0; i < 5; i++)
        {
                for (j = 0; (*p)[i][j] != '\0'; j++)
                {
                        printf("%c ", (*p)[i][j]);
                }
                printf("\n");
        }

        return 0;
}
红色部分为什么要多加一个‘ * ’,按照我自己的理解,指针数组指向的应该是整个数组,存放的是整个数组的地址,那么应该是(*p)[5]=&array;但是我试了一下会报错,
有大佬来帮忙解释一下这句语句的意思吗?
最佳答案
2021-9-30 13:29:13
#include<stdio.h>
int main()
{
        int c=1;
        int d=2;
        int* a=&c;
        int* b=&d;
        int **str[2]={&a,&b};
        int **(*p)[2]=&str;
        printf("%d",****p);
        return 0;
}
#include<stdio.h>
int main()
{
        int c=1;
        int d=2;
        int* a=&c;
        int* b=&d;
        int *str[2]={a,b};
        int *(*p)[2]=&str;
        printf("%d",***p);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-30 13:29:13 | 显示全部楼层    本楼为最佳答案   
#include<stdio.h>
int main()
{
        int c=1;
        int d=2;
        int* a=&c;
        int* b=&d;
        int **str[2]={&a,&b};
        int **(*p)[2]=&str;
        printf("%d",****p);
        return 0;
}
#include<stdio.h>
int main()
{
        int c=1;
        int d=2;
        int* a=&c;
        int* b=&d;
        int *str[2]={a,b};
        int *(*p)[2]=&str;
        printf("%d",***p);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-30 13:38:36 | 显示全部楼层
第一个问题:
因为数组的名字也可以代表这个数据的起始地址,所以可以不加&。

第二个问题:
咱们一步一步的来看:
(1)char array[5]是一个数组,里面存的是char类型的数据。

(2)char *array[5]是一个指针数组,说白了,也还是个数组,只不过这次数组中存放的是char类型的指针。
例如:此时array[0]的取出值是“FishC”这个字符串的首地址,
而*array[0]则是对该地址进行解引用,取出该地址中存储的值,即 ‘F’。

(3)char  *(*p)[5]对照着(2)来看,p就是一个指向指针数组的指针,
既然p是一个指针,那么它存储的必然是一个地址。只不过这个地址需要是char*[5]类型的地址(即指针数组的地址)
所以就有了char *(*p)[5] = &array;
这条语句相当于:
char *(*p)[5];//定义一个指向指针数组的指针p
p = &array;// 把array的地址赋值给p。

所以此时p指向的array这个指针数组的首地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-30 14:59:42 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-9-30 21:56:36 | 显示全部楼层
人造人 发表于 2021-9-30 14:59
C语言复杂声明解析

大佬,我看了那篇博客,按照我的理解应该是这样的
在定义的时候:
int* p
char* p都是说明p是一个指针,而*在定义的时候就是一个类型说明符
int** p说明p指向的是一个指针,对于下面这个
        char *array[5] = {"FishC", "Five", "Star", "Good", "WoW"};
        char *(*p)[5] = &array;
由于array[0]是一个字符串的首地址,说明数组指针p指向的数组包含的元素为指针,所以要在char (*P)[5]的基础上再加一个*进一步说明
我自己又写了一串代码
#include<stdio.h>
int main()
{
        int a=1;
        int b=2;
        int c=3;
        int d=4;
        int e=5;
        int *str[5]={&a,&b,&c,&d,&e};
        int *(*p)[5]=&str;
        printf("%d",***p);
}
但是我改成下面这样:
#include<stdio.h>
int main()
{
        int c=1;
        int d=2;
        int* a=&c;
        int* b=&d;
        int *str[2]={&a,&b};
        int **(*p)[2]=&str;
        printf("%d",****p);
}
会报错但是能运行
warning: initialization of 'int ** (*)[2]' from incompatible pointer type 'int * (*)[2]' [-Wincompatible-pointer-types]
    9 |         int **(*p)[2]=&str;
      |                       ^
1
这个是什么原因呢?难道说对于&str也有要求吗?但是根据博客说的,我加了三个*表明指针p指向的数组包含的元素(是个指针)指向的指针(我自己推的),每多一级指针多加一个*就可以了
最后再问一下,为啥数组指针指向二维数组的时候数组名前不需要加&符号?
我觉得是这样的:
指向一维数组的时候需要加&是要存放数组的地址
而二维数组的数组名相当于一维数组的地址
这样的解释对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 11:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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