鱼C论坛

 找回密码
 立即注册
查看: 1087|回复: 7

[已解决]int、int *形二维数组区别的疑问

[复制链接]
发表于 2020-8-29 16:58:01 | 显示全部楼层 |阅读模式

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

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

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

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

  4.     int a[] = {1, 3, 4};
  5.     int *k[] = {&a[0], &a[1], &a[2]};

  6.     printf("b    = %p\n", b);
  7.     printf("*b   = %p\n", *b);
  8.     printf("b[0] = %p\n", b[0]);
  9.     printf("\n");
  10.     printf("k    = %p\n", k);
  11.     printf("*k   = %p\n", *k);
  12.     printf("k[0] = %p\n", k[0]);

  13.     return 0;
  14. }
复制代码

运行结果
  1. b    = 0x7ffee997c6e0
  2. *b   = 0x7ffee997c6e0
  3. b[0] = 0x7ffee997c6e0

  4. k    = 0x7ffee997c6b0
  5. *k   = 0x7ffee997c6d4
  6. k[0] = 0x7ffee997c6d4
复制代码
最佳答案
2020-8-30 12:27:34
本帖最后由 sunrise085 于 2020-8-30 13:08 编辑
&a = a = a[0]数值相同,意义不同。
&a:二维数组a的首地址,&a+1 = a+sizeof(a) = a + 4*12  = a + 48
a:二维数组a的首元素地址,a+1 = a + 4*sizeof(int) = a + 16
a[0]:0的首地址,a[0] + 1 = a[0] + sizeof(int) = a[0] + 4

这一段理解的很透彻,完全正确!!
它们的确是地址相同意义不同,不同点就表现于自加跳过的字节数不一样。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

  6.     printf("b    = %p\n", b);
  7.     printf("*b   = %p\n", *b);
  8.     printf("b[0] = %p\n", b[0]);
  9.     printf("\n");
  10.     printf("k    = %p\n", k);
  11.     printf("*k   = %p\n", *k);
  12.     printf("k[0] = %p\n", k[0]);
  13.     printf("a[0] = %p\n", a[0]);
  14.     return 0;
  15. }
复制代码


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

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

  6.     printf("b    = %p\n", b);
  7.     printf("*b   = %p\n", *b);
  8.     printf("b[0] = %p\n", b[0]);
  9.     printf("\n");
  10.     printf("k    = %p\n", k);
  11.     printf("*k   = %p\n", *k);
  12.     printf("k[0] = %p\n", k[0]);
  13.     printf("a[0] = %p\n", a[0]);
  14.     return 0;
  15. }
复制代码


关于数组指针,可以看看这个帖子
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-29 22:50:42 | 显示全部楼层
本帖最后由 komodo 于 2020-8-29 22:51 编辑
sunrise085 发表于 2020-8-29 17:37
首先,你的程序中k不是二维数组,k只是个指针数组,是一个指针的数组,存放的是三个指针,三个指针分别指向 ...


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



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

使用道具 举报

 楼主| 发表于 2020-8-29 22:55:02 | 显示全部楼层
sunrise085 发表于 2020-8-29 17:37
首先,你的程序中k不是二维数组,k只是个指针数组,是一个指针的数组,存放的是三个指针,三个指针分别指向 ...
  1. int a[][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
  2.     int *k[] = {a[0],a[1],a[2]};
复制代码

“*k和k[0]都是数组二维数组a的首地址”,这句话不是很严谨,应该说*k和k[0]都是元素0的首地址,即一个int的地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-29 23:37:41 | 显示全部楼层
komodo 发表于 2020-8-29 22:55
“*k和k[0]都是数组二维数组a的首地址”,这句话不是很严谨,应该说*k和k[0]都是元素0的首地址,即一个 ...

a是个二维数组,
二维数组a的地址,一维数组a[0]的地址,还有int变量a[0][0]的地址是一样的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-30 08:50:09 | 显示全部楼层
sunrise085 发表于 2020-8-29 23:37
a是个二维数组,
二维数组a的首地址,一维数组a[0]的首地址,还有int变量a[0][0]的地址是一样的
  1. #include<stdio.h>
  2. int main(void){
  3.     int a[][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
  4.     int *k[] = {a[0],a[1],a[2]};
  5.     printf("&a     = %p\n", &a);
  6.     printf("a      = %p\n", a);
  7.     printf("a[0]   = %p\n", a[0]);
  8.     printf("&a+1   = %p\n", &a+1);
  9.     printf("a+1    = %p\n", a+1);
  10.     printf("a[0]+1 = %p\n", a[0]+1);
  11.     printf("\n");
  12.     printf("*k     = %p\n", *k);
  13.     printf("k[0]   = %p\n", k[0]);
  14.     printf("*k+1   = %p\n", *k+1);
  15.     printf("k[0]+1 = %p\n", k[0]+1);
  16.     return 0;
  17. }
  18. 运行结果
  19. &a       = 0x7ffee04666e0
  20. a         = 0x7ffee04666e0
  21. a[0]     = 0x7ffee04666e0
  22. &a+1   = 0x7ffee0466710
  23. a+1     = 0x7ffee04666f0
  24. a[0]+1 = 0x7ffee04666e4

  25. *k        = 0x7ffee04666e0
  26. k[0]     = 0x7ffee04666e0
  27. *k+1   = 0x7ffee04666e4
  28. k[0]+1 = 0x7ffee04666e4
复制代码

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

所以我觉得“*k和k[0]都是数组二维数组a的首地址”的说法不是很严谨,应该说*k和k[0]都是元素0的地址,即一个int的地址,刚学C语言比较较真,见谅哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-30 12:27:34 | 显示全部楼层    本楼为最佳答案   
本帖最后由 sunrise085 于 2020-8-30 13:08 编辑
&a = a = a[0]数值相同,意义不同。
&a:二维数组a的首地址,&a+1 = a+sizeof(a) = a + 4*12  = a + 48
a:二维数组a的首元素地址,a+1 = a + 4*sizeof(int) = a + 16
a[0]:0的首地址,a[0] + 1 = a[0] + sizeof(int) = a[0] + 4

这一段理解的很透彻,完全正确!!
它们的确是地址相同意义不同,不同点就表现于自加跳过的字节数不一样。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-3 20:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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