如果我有一个二维数组 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(实际上保存ints)的存储中读取字节,并假装这些字节是构成指针表示的字节。这是进一步的未定义行为(违反严格别名规则)。可能这样做的结果*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;是错误,所以未定义的行为!
注意:为避免此类错误,请在编译器选项中启用一些警告标志并尝试!