2016-04-08 4 views
-3

Вот код:Указатели в C с массивами

#include <stdio.h> 

int main() 
{ 
    int c[4][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}}; 
    int (*p)[3] = (int(*)[3])(c+2); 
    return 0; 
} 

Его Интересно, что она устанавливает р быть: {{8,9,10}, {11,12,13}, {14, 15, -8224}}

Я не понимаю, что происходит, особенно в 6-й строке кода. Пожалуйста, помогите мне!

+5

Есть ли причина, по которой вам нужно понять, что происходит в куске кода, который ничего не делает и написан таким образом, что никто никогда не должен писать код? –

+1

'(int (*) [3])' является * cast *, указателем на массив из трех целых чисел. Хотя выражение 'c + 2' равно' & c [2] ', которое является указателем на третий элемент' c'. –

+0

Да, мне нужно знать, потому что, на удивление, он устанавливает p {{8,9,10}, {11, 12, 13}, {14,15,0}}. – Debdut

ответ

1

int c[4][4] объявляет 2D-массив размером 4x4.

int (*p)[3] объявляет указатель на массив из 3 элементов.

(int(*)[3])(c+2) вызывает ошибку сглаживания указателя, обрабатывая адрес c+2, как если бы там был массив из 3 элементов.

Преобразование указателей между типами int (*)[4] (тип c+2) и тип int(*)[3] небезопасны. На практике большинство компиляторов, скорее всего, дадут вам определенный детерминированный результат из этого кода, но они не обязаны это делать. Программа может также сбой и сжигание, а затем это ошибка программиста.

+0

Я думаю, что неясно, есть ли ошибка наложения псевдонимов. '(int (*) [3]) (c + 2)' конечно, не является ошибкой псевдонимов, это актерский состав. Наверное, вы имеете в виду, что впоследствии чтение 'p [0] [0]' может быть ошибкой псевдонимов. Однако это lvalue типа 'int', и он обращается к объекту типа' int', который не нарушает строгое правило сглаживания. Стандарт здесь расплывчатый. (Конечно, есть ошибка доступа к границам) –

+0

@ M.M Я должен предположить, что они сделали трансляцию, потому что они действительно хотят использовать переменную где-то. Указанный тип будет массивом, а не int. Насколько я понимаю, массив из 3 элементов несовместим с массивом из 4 элементов. Еще одна проблема может заключаться в выравнивании, если 'int' является меньшим типом, чем требование выравнивания. Во всяком случае, дело в том, что просто не напишите странный код. – Lundin

+0

@ M.M А как насчет первого разыменования? p [0] является другим типом, чем c [0]. Это нарушение псевдонимов. – 2501

Смежные вопросы