Учитывая адрес указателя, как я могу получить то, на что он указывает? - PullRequest
0 голосов
/ 18 апреля 2011

Если мне дан адрес указателя, как мне получить то, на что указывает указатель?

Ответы [ 7 ]

5 голосов
/ 18 апреля 2011

Вы можете иметь в виду:

/**
  * @param pointer_to_pointer_to_int: the address of a pointer to an integer.
 **/
void function_that_takes_pointer_to_pointer(int **pointer_to_pointer_to_int) {
    int the_int = **pointer_to_pointer_to_int;
    printf("The pointer points to %d\n", the_int);
}
3 голосов
/ 18 апреля 2011

Предполагая, что это действительный указатель, вы можете разыменовать , используя унарный оператор *:

int *ptr = ...;
int x;
x = *ptr;
1 голос
/ 18 апреля 2011

Самый распространенный способ получить адрес указателя - через указатель на указатель. Если значение, на которое указывает указатель, является целым числом, тип адреса указателя будет int **.

Чтобы получить указатель на целое число, необходимо разыменовать двойной указатель. Затем вы можете разыменовать целочисленный указатель, чтобы получить целочисленное значение.

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

int **double_pointer = given;
int *int_pointer = *double_pointer;
int value = *int_pointer;

Вы также можете связать разыменования, чтобы сделать это в одной строке.

int **double_pointer = given;
int value = **double_pointer;
1 голос
/ 18 апреля 2011

Одинарный оператор *.

int *ptr = malloc(sizeof(int));
*ptr = 45;
printf("address: %p, value: %d", ptr, *ptr);
0 голосов
/ 19 апреля 2011

Если оставить комментарий RedX, если у вас есть ситуация, подобная

void foo(void *ptr)
{
  ...
}

, где значение ptr является указателем на указатель на int, например, вы можете сделать что-то вроде

void foo(void *ptr)
{
  int x = **((int **) ptr);
  ...
}

По сути, вы разыгрываете ptr на int **, затем дважды разыменовываете его.

Если вы не не знаете, какой тип цели опережает время (например, функция предназначена для обработки указателей на несколько типов), то вам придется вычислитьнайти способ кодировать информацию этого типа во втором аргументе и передать ее функции.

0 голосов
/ 19 апреля 2011

Существует два возможных ответа на ваш вопрос, в зависимости от того, имеет ли компилятор ключ к данным, на которые он ссылается, или нет.

Объявление указателя типа int *, char * или mytype * указывает компилятору, что более поздняя попытка разыменования его с помощью унарного оператора * должна привести к результату int, char или mytype соответственно.

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

int x = 5;
void *p = &x; /* p now points to an int, but the compiler doesn't know it */
printf("%d\n", *((int *) p)); /* we know what we did and don't rely on the compiler */
printf("%d\n", *p); /* compile-time error, dereferencing has undefined semantics */

Обратите внимание, что в скомпилированных неуправляемых языках, таких как C, отсутствует информация времени выполнения о том, на какие данные указывает указатель, в отличие от языков, таких как Java, где вы можете использовать оператор instanceof, чтобы проверить, на что действительно указывает ссылка во время выполнения.

0 голосов
/ 18 апреля 2011

Унарный оператор * возвращает или устанавливает значение в ячейке памяти.

Например:

int val = 42;
int* ptr = &val;
assert(val == *ptr);

Если у вас есть адрес указателя , вы бы написали **pointerpointer.

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