int num = * (int *) число; Что это делает? - PullRequest
12 голосов
/ 13 ноября 2010

Я искал какой-то код на С ++ и увидел это:

int num = *(int *)number;

Я никогда раньше такого не видел?это было в функции, помеченной так:

void *customer(void *number){ }

Что это вообще делает?Есть ли другой способ показать это?

Спасибо, это не домашняя работа, кстати, я просто запутался в том, что это делает?

Ответы [ 5 ]

13 голосов
/ 13 ноября 2010

Часть (int *) преобразует номер переменной в указатель на int, затем * перед ним разыменовывает его до int.

10 голосов
/ 13 ноября 2010

Функция принимает void*, но каким-то образом она знает (возможно, это требуется в какой-то документации), что данный указатель фактически указывает на int.

Итак, (int*)number естьисходный указатель, преобразованный в int*, чтобы я мог прочитать int из него ", а *(int*)number - это значение типа int, на которое он указывает.

2 голосов
/ 13 ноября 2010

Правильные ответы уже здесь, но могу ли я рассказать вам трюк, который обычно помог мне, когда мне приходилось много использовать C?

Это то, как вы произносите "*" в своей голове - и тамдве части.

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

То, что мне очень помогаетвсякий раз, когда вы видите * в своем коде - читайте его как «на что указывает».

Если вы следуете этому шаблону, то:

int num = *(int *)number;

является целочисленной переменной "num"получает назначенное значение: на что указывает указатель int, число.Он просто переводит сам себя.

Иногда вам приходится немного возиться с формулировками, но с тех пор, как я приобрел эту привычку, у меня никогда не возникало больших проблем с чтением кода указателя.

Я считаю, что я также читаю & как "адрес" в C, но я думаю, что он был перегружен в C ++, если я правильно помню.

1 голос
/ 13 ноября 2010

Я предполагаю, что customer используется так:

int lookup = 123;
customer_key *key = customer(&lookup);
// do something with key here

В этом случае код клиента настраивает тип void * до int *, а затем разыменовывает его (получая его значение). Сначала нужно выполнить типизацию, потому что void * в основном означает «указатель на что-то», что позволяет передавать любой тип, который вы хотите. Без преобразования типов компилятор не знает, хотите ли вы прочитать char (обычно 1 байт), short (обычно 2 байта) или int (обычно 4 байта). Typecast устраняет неоднозначность.

Обратите внимание, использование void * в качестве аргумента, вероятно, не лучшее, так как вы можете сделать:

double lookup = 69.0f;
customer_key *key = customer(&lookup);

И это скомпилируется, но не будет искать клиента 69 (double не int!).

Использование void * может быть преднамеренным, код может определять (надеюсь, безопасно) между указателями и аргументом, например: (void *)3 - это будет особый случай.

1 голос
/ 13 ноября 2010

Функция принимает пустой указатель (таким образом, void *).Чтобы разыменовать его с переменной определенного типа (например, int) - что и делает первый «*» - вам нужно привести его к указателю на фактический тип - в этом случае к указателю int через*) литой

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