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 首先,你的程序中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: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
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的地址。 komodo 发表于 2020-8-29 22:55
“*k和k都是数组二维数组a的首地址”,这句话不是很严谨,应该说*k和k都是元素0的首地址,即一个 ...
a是个二维数组,
二维数组a的首地址,一维数组a的首地址,还有int变量a的地址是一样的 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 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
这一段理解的很透彻,完全正确!!
它们的确是地址相同意义不同,不同点就表现于自加跳过的字节数不一样。 sunrise085 发表于 2020-8-30 12:27
这一段理解的很透彻,完全正确!!
他们地区是地址相同意义不同,不同点就表现于自加跳过的字节数不一样 ...
{:10_254:}
页:
[1]