2
  1. 如果我有一个二维数组 B 定义为:

    int B[2][3] = {{1,3,5},{2,4,6}};
    

    int **p = B一样吗int (*p)[3] = B

  2. int **f = B; printf("%d ",*f+1);

    给出5作为输出,而printf("%d ",*f)给出 1 作为答案。为什么会这样?

  3. printf("%d ",**f);

    返回分段错误!为什么?

4

2 回答 2

3
  1. int **p = B;是一个错误。(编译错误和逻辑错误)。一个int **必须指向一个int *. 但是,没有int *存储在B. B是一组int不涉及指针的连续 s。

  2. int **f = B;必须给出编译错误。结果生成的任何可执行文件的行为是完全未定义的。

  3. 见 2。


解释为什么你可能会看到15。(C 标准没有定义这一点,但无论如何你的编译器都在前面)。可能您的编译器将该行视为

int **f = (int **)B;

然后表达式*f将从B(实际上保存ints)的存储中读取字节,并假装这些字节是构成指针表示的字节。这是进一步的未定义行为(违反严格别名规则)。可能这样做的结果*f是指向地址的指针0x00000001

然后使用 打印指针%d,导致进一步的未定义行为。您会看到1,因为您的系统使用与传递相同的方法intprintf传递int *

当您将 1 添加到 时(int *)0x00000001,您会得到(int *)0x00000005,因为递增指针意味着指向该类型的下一个元素。

当您取消引用此指针时,它会导致段错误,因为该地址超出了您的有效地址空间。

于 2014-08-01T12:39:02.563 回答
1

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;是错误,所以未定义的行为!

注意:为避免此类错误,请在编译器选项中启用一些警告标志并尝试!

于 2014-08-01T12:45:10.607 回答