Что на самом деле делает эта строка кода `ptr = (char *) & a;`? - PullRequest
3 голосов
/ 27 сентября 2011

У меня есть код:

#include<stdio.h>
void main(){
   int i;
   float a=5.2;
   char *ptr;
   ptr=(char *)&a;
   for(i=0;i<=3;i++)
      printf("%d ",*ptr++);
}

Я получил вывод как 102 102 -90 64.Я не мог предсказать, как это произошло, я запутался с этой строкой ptr=(char *)&a;.Может кто-нибудь объяснить мне, что он делает?И как и другие переменные код *ptr++ увеличивается?Или есть другое правило для указателей в этом случае.

Я новичок в C, поэтому объясню ответ простыми словами.Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 27 сентября 2011

Это называется cast . В C приведение позволяет вам преобразовать или переосмыслить значение из одного типа в другой. Когда вы берете адрес float, вы получаете float*; приведение этого к char* дает вам указатель, ссылающийся на то же место в памяти, но притворяющийся, что то, что живет там, это char данные, а не float данные.

sizeof(float) равно 4, поэтому при печати четырех байтов, начиная с этого местоположения, вы получите байты, составляющие число с плавающей точкой, в соответствии с форматом IEEE-754 с одинарной точностью . У некоторых байтов установлены старшие биты, поэтому, когда они интерпретируются как signed char, а затем преобразуются в int для отображения, они отображаются как отрицательные значения из-за их представления с двумя дополнениями .

Выражение *ptr++ эквивалентно *(ptr++), которое сначала увеличивает ptr, а затем разыменовывает его предыдущее значение; вы можете думать об этом как об одновременном разыменовании и продвижении ptr.

6 голосов
/ 27 сентября 2011

Эта строка преобразует адрес a, обозначенный &a, в char*, то есть указатель на символы / байты.Затем цикл printf печатает значения четырех составляющих байтов a в десятичном виде.

(Кстати, было бы лучше, если бы цикл был

for (i=0; i<sizeof(a); i++)
    printf("%d ", ptr[i]);

)

2 голосов
/ 27 сентября 2011

Строка ptr=(char *)&a; приводит адрес переменной float к указателю типа char.Таким образом, вы теперь интерпретируете 4 байта, из которых состоит число с плавающей запятой, как единые байты, значения которых вы печатаете с помощью цикла for.

Оператор *ptr++ увеличивает значение указателя после считывания его значения,Это означает, что вы читаете значение, на которое указывает (отдельные байты с плавающей точкой), а затем перемещаете указатель на смещение в один байт.

1 голос
/ 27 сентября 2011

&a получает адрес a, то есть указатель типа float *.Этот указатель типа float * затем приводится к указателю типа char *.

Поскольку sizeof(char) == 1, a теперь можно видеть через ptr как последовательность байтов.

Это полезно, когда вы хотите абстрагировать тип переменной и рассматривать ее как конечную последовательность байтов, особенно это применимо при сериализации и хешировании.

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