Проблема с оператором sizeof () и объявлением указателя - PullRequest
0 голосов
/ 18 февраля 2020

Этот вопрос был задан на экзамене Sem-2. Вопрос попросил нас дать желаемый вывод.

int main(void)
{
    int a[] = {10,20,30,40,50,60};

    int (*p1)[2]=a , (*p2)[3]= a;

    if(sizeof(p1)==sizeof(p2))
    printf("%d",*(*p1+2));

    if(sizeof(*p1)==sizeof(*p2))
    printf("%d",*(*(p2+1)));

    return(0);
}

Предупреждения компилятора:

Warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
         initialization from incompatible pointer type [-Wincompatible-pointer-types]

Вывод, который я ожидаю: 20

Вывод, который я получаю при запуске : 30

Использование: g cc (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0

1 Ответ

2 голосов
/ 18 февраля 2020

Давайте проигнорируем неопределенное поведение, чтобы выяснить, что, вероятно, происходит.

p1 и p2 оба указывают на a[0] (игнорируя несовместимые типы указателей).

p1 и p2 оба указатели. Указатели на типы объектов обычно имеют одинаковый размер (предположим, что это так), поэтому sizeof(p1)==sizeof(p2) будет истинным.

p1 имеет тип int (*)[2], поэтому *p1 имеет тип int[2]. В большинстве выражений массив будет уменьшаться до указателя на его первый элемент, поэтому в выражении *(*p1+2), *p1 будет уменьшаться до int * и будет указывать на a[0]. Следовательно, *p1+2 будет указывать на a[2]. Поэтому *(*p1+2) будет таким же, как a[2], который имеет значение 30. Поэтому программа печатает 30.

Массив не затухает до указателя, когда он является операндом оператора sizeof. *p1 имеет тип int[2] и *p2 имеет тип int[3], поэтому sizeof(*p1)==sizeof(*p2) эквивалентно sizeof(int[2])==sizeof(int[3]), что неверно. Поэтому второй вызов printf, который печатает значение *(*p2+1), не оценивается.

(Давайте представим, что вызывается второй printf и вычисляется *(*p2+1). *p2 имеет тип int[3] и в этом выражении оно уменьшается до int *, указывающего на a[0]. Поэтому *p2+1 указывает на a[1]. Следовательно, *(*p2+1) будет таким же, как a[1],, который имеет значение 20. )

...