This question already has answers here:
One-dimensional access to a multidimensional array: is it well-defined behaviour?

(4个答案)


7年前关闭。




我的书(肯尼思·里克(Kenneth Reek)的《 Points on C》)指出,以下内容虽然可以正常工作,但却是非法的。
  int arr[5][5];
  int *p=&arr[2][2];
  p=p+3; // As array is stored in row major form I think this
         //should make p point to arr[3][0]

该书说,将每一行留给下一行是非法的。但是我不明白为什么。

最佳答案

我花了一会儿时间,我会尽力解释我认为他来自哪里,尽管没有读这本书,但这是最好的猜想。

首先,从技术上讲,您提议(或他提议)的增量是非法的;取消引用它。该标准使您可以将指针前进到数组序列的最后一个元素,该元素是从该序列中获取的最后一个元素,用于评估而不是取消引用。将其更改为p = p + 4,两者都是非法的。

除此之外,数组的线性足迹无法承受,ar[2]具有类型,并且它是int[5]。如果您不相信这些,请考虑以下内容,并正确输入所有内容:

int ar[5][5];
int (*sub)[5] = ar+2;   // sub points to 3rd row
int *col = *sub + 2;    // col points to 3rd column of third row.
int *p = col + 3;       // p points to 5th colum of third row.

这是否取决于ar[3][0]无关紧要您超出了参与指针数学的维度的声明大小。结果不能合法地取消引用,并且结果大于3偏移量,也不能合法地评估结果。

记住,要寻址的数组是ar[2];不仅是ar,而且says-same声明为size = 5。与其他两个相同的数组进行支持与当前正在执行的寻址无关。我认为,对于重复提出的问题,Christoph's answer应该是彻底解决方案中选择的那个。特别是,对 C99§6.5.6,p8 的引用,虽然有些冗长,但在下面显示为:



对不起,我认为与您的问题有关的内容是黑体字。通过按原样寻址,就可以离开要寻址的阵列,因此可以进入UB。简而言之,它可以工作(通常),但是不合法。

关于c - 为什么用C展平多维数组是非法的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22143494/

10-11 19:35