如果我将2d数组B定义为:
int B[2][3] = {{1,3,5},{2,4,6}};
int **p = B
与int (*p)[3] = B
相同吗?
int **f = B; printf("%d ",*f+1);
将5
作为输出,而printf("%d ",*f)
给出1作为答案。为什么
那是怎么回事?
printf("%d ",**f);
返回分段错误!为什么呢?
答案 0 :(得分:3)
没有。 int **p = B;
是一个错误。 (编译错误和逻辑错误)。 int **
必须指向int *
。但是,int *
中没有存储B
。 B
是一组没有指针的连续int
。
int **f = B;
必须提供编译错误。作为结果生成的任何可执行文件的行为是完全未定义的。
见2.
解释您可能会看到1
和5
的原因。 (C标准没有对此进行定义,但无论如何你的编译器都会向前推进)。可能你的编译器将该行视为
int **f = (int **)B;
然后表达式*f
将从B
(实际上保存int
s)的存储中读取字节,并假装那些是构成指针表示的字节。这是进一步未定义的行为(违反严格别名规则)。可能结果是*f
是指向地址0x00000001
的指针。
然后使用%d
打印指针,导致进一步的未定义行为。您看到1
,因为您的系统使用相同的方法将int
传递给printf
,就像传递int *
一样。
当你向(int *)0x00000001
添加1时,得到(int *)0x00000005
,因为递增指针意味着指向该类型的下一个元素。
当您取消引用此指针时,它会导致段错误,因为该地址超出了您的有效地址空间。
答案 1 :(得分:1)
1)int **p = b
与int (*p)[3] = b
相同吗? - 不。int **p = b
是错误。
因为int **p
是指向整数的指针,但是int (*p)[3]
是指向3个整数数组的指针!
2)int **f = B;
这是一个错误,可能导致未定义的行为!
3)printf("%d ",**f);
- 与(2)相同。 int **f = B;
是错误,因此未定义的行为!
注意:为避免此类错误,请在编译器选项中启用一些警告标志并尝试!