void * ptr = (int *) & a; не указывается ли указатель - PullRequest
0 голосов
/ 22 января 2020
#include<stdio.h> 
int main() 
{ 
    int a = 12; 
    void *ptr = (int *)&a; 
    printf("%d", *ptr);
    getchar(); 
    return 0; 
}

В приведенном выше коде в строке void *ptr = (int *)&a; указатель не относится к типу int?

Ответы [ 2 ]

1 голос
/ 22 января 2020

Чтобы сделать вещи короткими и простыми (без ссылки на стандарт, язык которого не помогает новичкам).

  1. Вы не можете разыменовать указатель void, и компилятор выдаст предупреждение и ошибки, если вы попытаетесь.

  2. Назначение не меняет тип объекта. void *ptr = (int *)another_pointer; не меняет тип ptr. Он по-прежнему void и не может быть разыменован.

Компилятор сообщит вам, если что-то не так (в большинстве случаев), как здесь: https://godbolt.org/z/Xm42eb

1 голос
/ 22 января 2020

За C 2018 6.5.16.1 1, когда левый операнд имеет тип void *, правый операнд может иметь тип int *:

Один из следующих должен содержать ... левый операнд имеет атоми c, квалифицированный или неквалифицированный тип указателя, и (учитывая тип, который левый операнд будет иметь после преобразования в lvalue) один операнд является указателем на тип объекта, а другой - указателем на квалифицированный или неквалифицированный версия void, а тип, на который указывает левый, имеет все квалификаторы типа, на который указывает правый…

Согласно 6.5.16.1 2, тогда правый операнд автоматически преобразуется в тип левый операнд:

… значение правого операнда преобразуется в тип выражения присваивания…

Таким образом, в (int *)&a значение &a, имеющий тип int *, преобразуется приведением в int *, что не имеет никакого эффекта. Затем для назначения оно автоматически преобразуется в void *, а результат сохраняется в ptr.

Тип ptr остается void *, как он объявлен. C не будет автоматически отслеживать, что значение в ptr происходит от int *.

...