指针指针和指向2d数组的指针之间的区别

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

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

    int **p = Bint (*p)[3] = B吗?

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

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

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

    返回分段错误! 为什么?

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

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

  3. 见2。


解释为什么你可能会看到15 。 (C标准没有对此进行定义,但无论如何你的编译器都会向前推进)。 可能你的编译器将该行视为

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

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

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

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

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

1) int **p = bint (*p)[3] = b ? – 编号int **p = b是错误。

因为这里int **p是指向整数的指针,但是int (*p)[3]是指向3个整数数组的指针!

2) int **f = B; 这是一个错误,可能导致未定义的行为!

3) printf("%d ",**f); – 与(2)相同。 int **f = B; 是错误,所以未定义的行为!

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