komodo 发表于 2020-8-29 16:58:01

int、int *形二维数组区别的疑问

本帖最后由 komodo 于 2020-8-29 17:13 编辑

【现象】对于int形二维数组b来说,b=*b=b,原因是int形二维数组是线性排列,所以三者相同;对于int*二维数组来说,k的值是指针数组k第一个元素的地址,而*k和k则是该地址上存储的int变量所在的地址,所以*k=k,不等于k
【问题】分开来看,两种结果都能各自解释通,但是放在一起看,既然他们都是二维数组,难道我必须需要要分开考虑吗?
#include<stdio.h>
int main(void){
    int b[] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};

    int a[] = {1, 3, 4};
    int *k[] = {&a, &a, &a};

    printf("b    = %p\n", b);
    printf("*b   = %p\n", *b);
    printf("b = %p\n", b);
    printf("\n");
    printf("k    = %p\n", k);
    printf("*k   = %p\n", *k);
    printf("k = %p\n", k);

    return 0;
}
运行结果
b    = 0x7ffee997c6e0
*b   = 0x7ffee997c6e0
b = 0x7ffee997c6e0

k    = 0x7ffee997c6b0
*k   = 0x7ffee997c6d4
k = 0x7ffee997c6d4

sunrise085 发表于 2020-8-29 17:37:26

首先,你的程序中k不是二维数组,k只是个指针数组,是一个指针的数组,存放的是三个指针,三个指针分别指向一维数组a的三个int类型的数据地址
然后,你所说的这两个东西根本就不是一回事儿,一个是二维数组,一个是一维指针数组,即使这些指针都指向一个一维数组,他们也不能称之为二维数组。
如下面程序,*k和k都是数组二维数组a的首地址,但是k并不是,k是数组k的地址。实际上,int *k[]应该写成 (int*) k[],首先它是一个一维数组,然后该数组的元素都是指针,这是指针数组,这正是你弄错的地方
#include<stdio.h>
int main(void){
    int b[] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};

    int a[] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
    int *k[] = {a,a,a};

    printf("b    = %p\n", b);
    printf("*b   = %p\n", *b);
    printf("b = %p\n", b);
    printf("\n");
    printf("k    = %p\n", k);
    printf("*k   = %p\n", *k);
    printf("k = %p\n", k);
    printf("a = %p\n", a);
    return 0;
}

最后,再跟你说说这个知识点正确的是什么。二维数组,和一维数组指针是一样的。划重点:是一维数组指针,不是一维指针数组。下面这个程序中才是数组指针,所谓数组指针,首先它是指针,然后他指向的是一维数组
#include<stdio.h>
int main(void){
    int b[] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};

    int a[] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
    int (*k) = a;

    printf("b    = %p\n", b);
    printf("*b   = %p\n", *b);
    printf("b = %p\n", b);
    printf("\n");
    printf("k    = %p\n", k);
    printf("*k   = %p\n", *k);
    printf("k = %p\n", k);
    printf("a = %p\n", a);
    return 0;
}

关于数组指针,可以看看这个帖子

komodo 发表于 2020-8-29 22:50:42

本帖最后由 komodo 于 2020-8-29 22:51 编辑

sunrise085 发表于 2020-8-29 17:37
首先,你的程序中k不是二维数组,k只是个指针数组,是一个指针的数组,存放的是三个指针,三个指针分别指向 ...

感谢回复,指针数组确实和二维数组确实不是一回事儿,定义一个二维指针数组的形式为int *p,即数组p是一个二维数组,且每个元素都是一个指针,但是我还是有如下疑问,用你的例子来讲:
【疑问】即使指针数组k可以用k[][]的形式定位一个int值,也不能认为k是一个二维数组对吧?
int a[] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
    int *k[] = {a,a,a};
    printf("k = %d\n", k);
    printf("*(*k+1) = %d\n", *(*k+1));
// 运行结果
k = 1
*(*k+1) = 1


komodo 发表于 2020-8-29 22:55:02

sunrise085 发表于 2020-8-29 17:37
首先,你的程序中k不是二维数组,k只是个指针数组,是一个指针的数组,存放的是三个指针,三个指针分别指向 ...

int a[] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
    int *k[] = {a,a,a};
“*k和k都是数组二维数组a的首地址”,这句话不是很严谨,应该说*k和k都是元素0的首地址,即一个int的地址。

sunrise085 发表于 2020-8-29 23:37:41

komodo 发表于 2020-8-29 22:55
“*k和k都是数组二维数组a的首地址”,这句话不是很严谨,应该说*k和k都是元素0的首地址,即一个 ...

a是个二维数组,
二维数组a的首地址,一维数组a的首地址,还有int变量a的地址是一样的

komodo 发表于 2020-8-30 08:50:09

sunrise085 发表于 2020-8-29 23:37
a是个二维数组,
二维数组a的首地址,一维数组a的首地址,还有int变量a的地址是一样的

#include<stdio.h>
int main(void){
    int a[] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
    int *k[] = {a,a,a};
    printf("&a   = %p\n", &a);
    printf("a      = %p\n", a);
    printf("a   = %p\n", a);
    printf("&a+1   = %p\n", &a+1);
    printf("a+1    = %p\n", a+1);
    printf("a+1 = %p\n", a+1);
    printf("\n");
    printf("*k   = %p\n", *k);
    printf("k   = %p\n", k);
    printf("*k+1   = %p\n", *k+1);
    printf("k+1 = %p\n", k+1);
    return 0;
}
运行结果
&a       = 0x7ffee04666e0
a         = 0x7ffee04666e0
a   = 0x7ffee04666e0
&a+1   = 0x7ffee0466710
a+1   = 0x7ffee04666f0
a+1 = 0x7ffee04666e4

*k      = 0x7ffee04666e0
k   = 0x7ffee04666e0
*k+1   = 0x7ffee04666e4
k+1 = 0x7ffee04666e4
&a = a = a数值相同,意义不同。
&a:二维数组a的首地址,&a+1 = a+sizeof(a) = a + 4*12= a + 48
a:二维数组a的首元素地址,a+1 = a + 4*sizeof(int) = a + 16
a:0的首地址,a + 1 = a + sizeof(int) = a + 4
*k= k= a = 0的首地址,所以*k+1 = *k+sizeof(int) = *k+4

所以我觉得“*k和k都是数组二维数组a的首地址”的说法不是很严谨,应该说*k和k都是元素0的地址,即一个int的地址,刚学C语言比较较真,见谅哈{:5_109:}

sunrise085 发表于 2020-8-30 12:27:34

本帖最后由 sunrise085 于 2020-8-30 13:08 编辑

&a = a = a数值相同,意义不同。
&a:二维数组a的首地址,&a+1 = a+sizeof(a) = a + 4*12= a + 48
a:二维数组a的首元素地址,a+1 = a + 4*sizeof(int) = a + 16
a:0的首地址,a + 1 = a + sizeof(int) = a + 4
这一段理解的很透彻,完全正确!!
它们的确是地址相同意义不同,不同点就表现于自加跳过的字节数不一样。

komodo 发表于 2020-8-30 13:03:31

sunrise085 发表于 2020-8-30 12:27
这一段理解的很透彻,完全正确!!
他们地区是地址相同意义不同,不同点就表现于自加跳过的字节数不一样 ...

{:10_254:}
页: [1]
查看完整版本: int、int *形二维数组区别的疑问