С учетом объявления
int x[2][3] = {{1,2,3},{4,5,6}};
тип выражения x[1]
равен "3-элементному массиву int
".Если выражение массива не является операндом оператора адресации sizeof
или &
или не является строковым литералом, используемым для инициализации другого массива в объявлении, тип выражения преобразуется в «указатель на T» изначение выражения является адресом первого элемента массива.
Следовательно, в объявлении
int *y1 = (int *) x[1];
приведение не требуется;x[1]
будет автоматически преобразован в тип int *
, а y1
будет указывать на x[1][0]
.
В объявлении
int *y2 = (int *) &x[1];
выражение массива x[1]
является операндом оператора address-of &
, поэтому оно не преобразуется автоматически в тип int *
.Тип выражения &x[1]
- это «указатель на массив из 3 элементов int
» или int (*)[3]
.В этом случае приведение необходимо, поскольку вы не можете неявно преобразовать указатель в массив T для указателя на T. Однако, вероятно, это не то, что вы хотите сделать;преобразование указателя в массив в указатель на скаляр, вероятно, приведет к путанице со стороны кого-либо.
Обратите внимание, что x[1]
и &x[1]
дают одинаковое значение (адрес первого элемента в массиве совпадает с адресом самого массива), но типы различны, что будет иметь значение для таких вещей, как операторы ++
и --
.
Если вы хотите избежать приведений, перепишите эти объявления как
int *y1 = x[1];
int (*y2)[3] = &x[1];