Давайте проанализируем ваш код построчно:
char x[16];
x
- это «массив [16] из char
», то есть он может хранить 16 char
значений. Кстати, вы вообще не используете x
в своем коде.
int y = 42 + 256;
y
- это int
, равный 298.
char* p = &y;
p
- указатель на char
, и вы пытаетесь присвоить ему адрес int
. Если вы хотите указатель на int
, вы должны объявить p
как int *p
, или, если вы хотите универсальный указатель, вы должны объявить его как void *p
. Если вы действительно хотите делать то, что делаете, вам нужен актерский состав: char *p = (char *)&y;
. Результатом вашей инициализации p
является то, что p
указывает на младший адресуемый байт y
.
int* q = p;
q
относится к типу int *
, а p
относится к типу char *
. Опять же, вам нужен актерский состав. Предполагая приведение, стандарт говорит это о ваших последних двух утверждениях:
Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель не правильно выровнен для указанного типа, поведение не определено. В противном случае при обратном преобразовании
Результат должен сравниться с исходным указателем.
Итак, чистый эффект такой, как если бы вы сделали: int *q = &y;
. Итак, q
содержит адрес y
.
char **r = &p;
r
относится к типу char **
. &p
относится к типу int **
. Опять же, вам нужен как минимум бросок, но вы не можете переносить int **
в char **
. Я не уверен, почему вы используете char **
в любом случае. Если вам нужен адрес p
в переменной, вы должны использовать void *
, или, если вы действительно хотите char
, использовать char *
.
printf("%d %d %d\n", p, q, r);
Вы печатаете указатели с указателем формата %d
. %d
занимает int
, а не указатель. Для печати следует использовать %p
и использовать p
, q
и r
до void *
.
Предполагая, что я понял, что вы хотели сделать, я переписал вашу программу:
#include <stdio.h>
int main(void)
{
int y = 42 + 256;
void *p = &y;
void *q = p;
void *r = &p;
printf("%p %p %p\n", p, q, r);
return 0;
}
На моем компьютере это печатает:
0x7fff5fbff7dc 0x7fff5fbff7dc 0x7fff5fbff7d0
p
и q
явно равны, а r
- адрес объекта p
.
Если я не правильно понял ваше намерение, вы должны сообщить нам, что вы пытаетесь сделать и почему.