Значение ссылки и разыменования в C

Я читал разные вещи в Интернете и запутался, потому что на каждом сайте написано разное.

Я читал об * операторе ссылки и & операторе разыменования; или что ссылка означает, что указатель указывает на переменную, а разыменование — это доступ к значению переменной, на которую указывает указатель. Так что я запутался.

Могу ли я получить простое, но подробное объяснение «ссылки и разыменования»?


person Milkncookiez    schedule 08.01.2013    source источник
comment
Обратите внимание, что официальными именами являются адрес (&) и оператор косвенности (*).   -  person Daniel Fischer    schedule 09.01.2013
comment
Вы перепутали операторов. * — оператор разыменования.   -  person cheznead    schedule 06.04.2015
comment
Возможный дубликат Что означает разыменование указателя?   -  person jww    schedule 15.03.2018


Ответы (7)


Ссылка означает использование адреса существующей переменной (используя &) для установки переменной-указателя. Чтобы быть действительным, указатель должен быть установлен на адрес переменной того же типа, что и указатель, без звездочки:

int  c1;
int* p1;
c1 = 5;
p1 = &c1;
//p1 references c1

Разыменование указателя означает использование оператора * (символ звездочки) для извлечения значения из адреса памяти, на который указывает указатель: ПРИМЕЧАНИЕ. Значение, хранящееся по адресу указателя, должно быть значением OF ТОТ ЖЕ ТИП, что и тип переменной, на которую «указывает» указатель, но нет гарантии, что это так, если только указатель не был установлен правильно. Тип переменной, на которую указывает указатель, — это тип за вычетом самой внешней звездочки.

int n1;
n1 = *p1;

Invalid dereferencing may or may not cause crashes:

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

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

Рекомендации:

http://www.codingunit.com/cplusplus-tutorial-pointers-reference-and-dereference-operators

& is the reference operator and can be read as “address of”.
* is the dereference operator and can be read as “value pointed by”.

http://www.cplusplus.com/doc/tutorial/pointers/

& is the reference operator    
* is the dereference operator

http://en.wikipedia.org/wiki/Dereference_operator

The dereference operator * is also called the indirection operator.
person A B    schedule 08.01.2013

Я всегда слышал, как они используются в противоположном смысле:

  • & — это оператор ссылки — он дает вам ссылку (указатель) на некоторый объект

  • * — это оператор разыменования — он принимает ссылку (указатель) и возвращает вам объект, на который указывает ссылка;

person Chris Dodd    schedule 08.01.2013

Во-первых, они расположены в обратном порядке: & — ссылка, а * — разыменование.

Ссылка на переменную означает доступ к адресу памяти переменной:

int i = 5;
int * p;
p = &i; //&i returns the memory address of the variable i.

Разыменование переменной означает доступ к переменной, хранящейся по адресу памяти:

int i = 5;
int * p;
p = &i;
*p = 7; //*p returns the variable stored at the memory address stored in p, which is i.
//i is now 7
person ApproachingDarknessFish    schedule 08.01.2013
comment
Подождите, адрес памяти переменной i не 5, 5 — это значение i. Не так ли? Адрес памяти должен быть примерно таким.. 0XA234948... который нам не нужно знать. - person Nayana; 25.03.2013
comment
@dockbudu Правильно. Значение i равно 5, адрес памяти будет некоторым значением, которое мы не можем контролировать (часто выражается в шестнадцатеричном формате). - person ApproachingDarknessFish; 25.03.2013

найти следующее объяснение:

int main()
{
    int a = 10;// say address of 'a' is 2000;
    int *p = &a; //it means 'p' is pointing[referencing] to 'a'. i.e p->2000
    int c = *p; //*p means dereferncing. it will give the content of the address pointed by 'p'. in this case 'p' is pointing to 2000[address of 'a' variable], content of 2000 is 10. so *p will give 10. 
}

вывод :

  1. & [оператор адреса] используется для ссылки.
  2. * [оператор звездочки] используется для разыменования.
person nagaradderKantesh    schedule 09.01.2013

Контекст, в котором находится *, иногда путает значение.

  // when declaring a function
int function(int*); // This function is being declared as a function that takes in an 'address' that holds a number (so int*), it's asking for a 'reference', interchangeably called 'address'. When I 'call'(use) this function later, I better give it a variable-address! So instead of var, or q, or w, or p, I give it the address of var so &var, or &q, or &w, or &p.   

//even though the symbol ' * ' is typically used to mean 'dereferenced variable'(meaning: to use the value at the address of a variable)--despite it's common use, in this case, the symbol means a 'reference', again, in THIS context. (context here being the declaration of a 'prototype'.) 


    //when calling a function
int main(){ 
    function(&var);  // we are giving the function a 'reference', we are giving it an 'address'
  }

Таким образом, в контексте объявления типа, такого как int или char, мы использовали бы разыменование ' * ' для фактического обозначения ссылка (адрес), что сбивает с толку, если вы видите сообщение об ошибке от компилятора, говорящее: «ожидание char*», которое запрашивает адрес.

В этом случае, когда * стоит после типа (int, char и т. д.), компилятор ожидает адрес переменной. Мы даем ему это с помощью оператора ссылки, также называемого оператором address-of ' & ' перед переменной. Более того, в случае, который я только что описал выше, компилятор ожидает, что адрес будет содержать символьное значение, а не число. (введите char * == адрес символьного значения)

int* p;
int *a;   // both are 'pointer' declarations. We are telling the compiler that we will soon give these variables an address (with &).

int c = 10;  //declare and initialize a random variable
//assign the variable to a pointer, we do this so that we can modify the value of c from a different function regardless of the scope of that function (elaboration in a second)

p = c; //ERROR, we assigned a 'value' to this 'pointer'. We need to assign an 'address', a 'reference'.
p = &c; // instead of a value such as: 'q',5,'t', or 2.1 we gave the pointer an 'address', which we could actually print with printf(), and would be something like
//so
p = 0xab33d111; //the address of c, (not specifically this value for the address, it'll look like this though, with the 0x in the beggining, the computer treats these different from regular numbers)
*p = 10; // the value of c

a = &c; // I can still give c another pointer, even though it already has the pointer variable "p"

*a = 10;
 a = 0xab33d111;

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

//Why it's used
int function(b){
    b = b + 1; // we just want to add one to any variable that this function operates on.
} 

int main(){

    int c = 1;  // I want this variable to be 3.

    function(c); 
    function(c);// I call the function I made above twice, because I want c to be 3.

     // this will return c as 1. Even though I called it twice.
     // when you call a function it makes a copy of the variable.
     // so the function that I call "function", made a copy of c, and that function is only changing the "copy" of c, so it doesn't affect the original
}
  //let's redo this whole thing, and use pointers

int function(int* b){ // this time, the function is 'asking' (won't run without) for a variable that 'points' to a number-value (int). So it wants an integer pointer--an address that holds a number.
*b = *b + 1; //grab the value of the address, and add one to the value stored at that address
}

int main(){
    int c = 1; //again, I want this to be three at the end of the program
    int *p = &c; // on the left, I'm declaring a pointer, I'm telling the compiler that I'm about to have this letter point to an certain spot in my computer. Immediately after I used the assignment operator (the ' = ') to assign the address of c to this variable (pointer in this case) p. I do this using the address-of operator (referencer)' & '.
    function(p); // not *p, because that will dereference. which would give an integer, not an integer pointer ( function wants a reference to an int called int*, we aren't going to use *p because that will give the function an int instead of an address that stores an int.

    function(&c); // this is giving the same thing as above, p = the address of c, so we can pass the 'pointer' or we can pass the 'address' that the pointer(variable) is 'pointing','referencing' to. Which is &c. 0xaabbcc1122...


      //now, the function is making a copy of c's address, but it doesn't matter if it's a copy or not, because it's going to point the computer to the exact same spot (hence, The Address), and it will be changed for main's version of c as well.

}

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

person Tyler Curtis Jowers    schedule 30.07.2018

Ссылка

& — оператор ссылки. Он будет ссылаться на адрес памяти на переменную указателя.

Пример:

int *p;
int a=5;
p=&a; // Here Pointer variable p refers to the address of integer variable a.

Разыменование

Оператор разыменования * используется переменной-указателем для прямого доступа к значению переменной вместо ее адреса в памяти.

Пример:

int *p;
int a=5;
p=&a;
int value=*p; // Value variable will get the value of variable a that pointer variable p pointing to.
person zaursh    schedule 18.04.2018

Ссылка разыменованного указателя также совпадает с адресом указанной переменной.

Объяснение :-

интервал переменная = 3; интервал *р;

р =

Итак, давайте подумаем, что адрес var: ABCDE

потом,

p = ABCDE и &*p = ABCDE;

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


также при объявлении функции,

аргументы функции должны быть указателями,

и в аргументах этой функции при вызове ее в основном методе должен быть оператор &.

это немного сбивает с толку. Но помните, что int *p = также правильно, как приведенное выше объявление указателя.

person Dasun wijesundara    schedule 29.11.2020
comment
Пожалуйста, не добавляйте новый ответ, если хотите добавить больше информации, вместо этого используйте кнопку редактирования и отредактируйте исходный ответ, вы должны сохранить этот ответ и удалить уменьшенную версию, также вы должны отредактировать ответ и отформатировать свой код (выберите и нажмите фигурную кнопку скобки в редакторе) - person Ruli; 29.11.2020