Понимание типов и значений указателей - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь понять указатели, их значения и типы

допустим, у меня есть int x:

int x = 0;
int* ip = &x; 

Я знаю, что значение здесь - это адрес x, скажем, это 123.

*ip += 1 

Значение теперь 124? (адрес + 1). Я пытаюсь понять, что происходит со значением и введите здесь:

float *fp = (float*)ip; 
*fp = 1.0; 
int y = *ip;

Ответы [ 2 ]

0 голосов
/ 24 января 2019
int x = 0;
int* ip = &x;  /*I know the value here is the address of x, let's say it is 123*/
printf("\n%u",ip); //value is 123
printf("\n%u",*ip);// value is 0
*ip += 1; //*ip points to the value of the stored address i.e. x and increase it by 1 
printf("\n%u",ip); //value is 123
printf("\n%u",*ip); //value is 1

float *fp = (float*) ip; converting address inside ip i.e. 123 into float type and store in fp
printf("\n%u",fp); //value is 123
printf("\n%f",*fp);//points to the value of stored address i.e. value at 123. 0.000000 is the value as we have converted it to float from int it got initialized to 0
*fp = 1.0; //storing the value to address 123

printf("\n%f",*fp);//value is 1.000000
int y = *ip;//storing the value

printf("\n%f",y);//it will also gives 1.000000

Здесь я не объясняю внутренние преобразования между float и int.Просто объясняю, как работает указатель

0 голосов
/ 24 января 2019

Если вы установите указатель на адрес переменной, а затем выполните разыменование, вы измените значение на указателе, а не на сам адрес.Так что если вы пишете ip += 1, который меняет адрес, а *ip +=1 меняет значение по адресу.

Вот несколько примеров, которые должны помочь прояснить, как работают указатели, в том числе со значениями с плавающей запятой.Вы должны прочитать о представлении IEEE754 32-разрядных чисел с плавающей точкой, чтобы лучше понять, почему 1.0 представляется как 0x3f800000.

Обратите внимание, что этот код делает много предположений о размерах типов (которые являются реализациейопределены!) и игнорирует правила псевдонимов (нельзя указывать на объект в памяти с типом указателя, который не соответствует объявленному типу объекта, а затем разыменовывать этот указатель).Тем не менее, на практике вы всегда можете интерпретировать любую память как биты, даже если она «небезопасна» или «незаконна».

int x = 0;
int* ip = &x;
*ip += 1; // x = 1
ip += 1; // ip is now increased by sizeof(int) and probably points to
        // the gap in the stack between x and ip, since sizeof(x) is probably 4
        // and ip is probably 8 byte aligned
ip += 1; // now ip probably points to itself! (the address points to its own address value)
ip -= 2; // now ip points to x again
*ip += 2; // now x = 3

float *fp = (float*)ip; // the value *fp is the same in binary, 0b11
int z = *(int *)fp;    // z is 3, because we're preventing the conversion
*fp = 1.0;            // in hex, *fp is 0x3f800000
int y = *fp;         // 1.0 is converted to int and stored in y as 1
int a = *(int *)fp; // a is 0x3f800000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...