Получение адреса указателя в C с и без амперсанда, в чем разница? - PullRequest
0 голосов
/ 01 декабря 2018

Мне трудно понять код этого руководства по указателям в C .Я подумал, что вам нужен амперсанд для ссылки на адрес указателя, но код руководства удается получить его без такового.Я изменил их код одним изменением, которое я прокомментировал как «МОЯ ДОБАВЛЕННАЯ ЛИНИЯ».Эта линия идентична линии над ней, но с добавлением амперсанда.Оценки этих линий дают очень похожие значения, но не идентичные значения.Куда движется моя логика на юг?

Спасибо, Накул

  #include <stdio.h>

int main () {

   int  var = 20;   /* actual variable declaration */
   int  *ip;        /* pointer variable declaration */

   ip = &var;  /* store address of var in pointer variable*/

   printf("Address of var variable: %x\n", &var  );

   /* address stored in pointer variable */
   printf("Address stored in ip variable: %x\n", ip );

  /* MY ADDED LINE: address stored in pointer variable */
   printf("Address stored in ip variable: %x\n", &ip );


   /* access the value using the pointer */
   printf("Value of *ip variable: %d\n", *ip );

   return 0;

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

вы использовали

int var = 20;
int *ip;
ip = &var;

и напечатали &var, ip, &ip *ip

Здесь &var и ip будут указывать адрес памяти, в которой сохранено 20.И *ip укажет значение 20. И самое главное, что вы хотели, это &ip.Когда вызывается int *ip, будет создана область памяти для этой переменной.поэтому ip занимают некоторую область памяти.Когда вы печатаете &ip, это будет указывать адрес памяти, на котором сохранено ip(contains the address of var).

0 голосов
/ 01 декабря 2018

Указатель - это просто обычная переменная, которая содержит адрес чего-то другого в качестве значения.Другими словами, указатель указывает на адрес, где можно найти что-то еще.Если вы обычно думаете о переменной, содержащей непосредственные значения, такие как int a = 5;, указатель будет просто содержать адрес, где 5 хранится в памяти, например, int *b = &a;.

Будучи нормальной переменной,сам указатель имеет адрес.Его адрес - это адрес самой переменной, а не адрес, который она хранит.Например, char buf[] = "foo", *p = buf; создает массив buf и назначает адрес для первого символа в buf в качестве адреса , содержащегося в p (например, p указывает на первый символ в buf).Но у p есть адрес в памяти.Именно по адресу p адрес первой буквы в buf хранится в памяти.Краткий пример может помочь:

#include <stdio.h>

int main (void) {

    char buf[] = "foo",
        *p = buf;

    printf ("address for buf      : %p\n"
            "address of 1st char  : %p\n"
            "address held by p    : %p\n"
            "address for p itself : %p\n",
            (void*)buf, (void*)&buf[0], (void*)p, (void*)&p);
}

Пример Использование / Вывод

$ ./bin/pointeraddr
address for buf      : 0x7fffbfd0e530
address of 1st char  : 0x7fffbfd0e530
address held by p    : 0x7fffbfd0e530
address for p itself : 0x7fffbfd0e540

Теперь давайте посмотрим ближе, что содержит указатель и адрес указателя (где чтоудержание указателя удерживается в памяти) Давайте просто для простоты будем использовать последние три числа в адресах.

Где находится массив с символом buf, хранящийся в памяти?

    +---+---+---+---+
    | f | o | o | \0|   buf - array of char
    +---+---+---+---+
      5   5   5   5
      3   3   3   3
      0   1   2   3

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

(p3) За исключением случаев, когда он является операндом оператора sizeof, оператор _Alignof, или унарный оператор '&', или строковый литерал , используемый для инициализации массива, выражение с типом «массив типа» преобразуетсяна выражение с типом "указатель на тип" , которое указывает на начальный элемент объекта массива и не является lvalue.

C11 Standard - 6.3.2.1Другие операнды - L-значения, массивы и обозначения функций (p3)

Какой первый символ в массиве buf?(ответ: buf[0]) Каков адрес первого символа (с помощью унарного оператора '&')?Он совпадает с адресом buf, но имеет указатель типа на символ (в отличие от buf, который при обращении является указателем на массив из char[4])

А как же p?У него есть собственный адрес, в котором хранится адрес первого символа в buf, например,

    +---+  p - pointer to char
    | 5 |
    | 3 |  holds the address 0x7fffbfd0e530
    | 0 |
    +---+
      5
      4    stored at 0x7fffbfd0e540
      0

Как получить значение (символ) по адресу, который хранится в p?Вы используете одинарный разыменование оператор *p.Как вы получаете адрес, удерживаемый p?p уже является указателем, поэтому простая оценка p сама дает адрес, который хранится в p, например,

char *q = p;

q теперь содержит адрес, который хранится в p, сохраненном в новомадрес, в котором q создается в памяти.

Или, очень просто, распечатать адрес, который хранится в p, который теперь также хранится в q, просто приведите p (или q) к(void*) и печать с указателем преобразования "%p" , например,

printf ("address held by p & q : %p\n", (void*)p);

Без магии.Указатель - это просто переменная, которая содержит адрес чего-то другого в качестве значения.Как и у любой переменной, у нее есть собственный адрес.Если вы думаете об этом таким образом, вы всегда можете выяснить, что у вас есть - и что вам нужно сделать, чтобы получить значение, хранящееся по этому адресу.

Просмотрите вещи и дайте мне знать, если у вас есть дальнейшиевопросы.

0 голосов
/ 01 декабря 2018

Логика идет на юг, потому что «&» дает вам указатель (в вашем случае указатель на указатель).Позвольте мне скорректировать ваш код с правильной терминологией, тогда должно стать ясно:

printf("Address stored in ip variable, pointing to
    the memory location of var: %x\n", ip );

printf("Address pointing to the (memory location / address)
    of pointer ip which itself contains the (memory location / 
    address) of var: %x\n", &ip );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...