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