C中“引用”和“取消引用”的含义

Posted

技术标签:

【中文标题】C中“引用”和“取消引用”的含义【英文标题】:Meaning of "referencing" and "dereferencing" in C 【发布时间】:2012-12-22 21:17:26 【问题描述】:

我在互联网上阅读了不同的内容并感到困惑,因为每个网站都说不同的东西。

我读到了* 引用运算符和& 取消引用运算符;或者引用意味着使指针指向变量,而取消引用是访问指针指向的变量的值。所以我很困惑。

我能得到一个关于“引用和解除引用”的简单而透彻的解释吗?

【问题讨论】:

请注意,正式名称是地址(&)和间接(*)运算符。 你把运营商搞混了。 * 是取消引用运算符。 What does "dereferencing" a pointer mean?的可能重复 【参考方案1】:

引用 表示获取现有变量的地址(使用&)来设置指针变量。 为了有效,指针必须设置为与指针相同类型的变量的地址,不带星号:

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

取消引用指针意味着使用 * 运算符(星号字符)从指针指向的内存地址中检索值: 注意:存储在指针地址的值必须是与指针“指向”的变量类型相同类型的值,但不能保证除非指针设置正确。指针指向的变量类型是减去最外层星号的类型。

int n1;
n1 = *p1;

无效的取消引用可能会也可能不会导致崩溃:

取消引用未初始化的指针可能会导致崩溃 使用无效类型转换取消引用可能会导致崩溃。 取消引用指向动态分配并随后解除分配的变量的指针可能会导致崩溃 取消引用指向已超出范围的变量的指针也可能导致崩溃。

无效引用比崩溃更容易导致编译器错误,但为此依赖编译器并不是一个好主意。

参考资料:

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.

【讨论】:

【参考方案2】:

我总是听到它们被用在相反的意义上:

& 是引用运算符 -- 它为您提供指向某个对象的引用(指针)

* 是解引用运算符——它接受一个引用(指针)并返回被引用的对象;

【讨论】:

【参考方案3】:

首先,您将它们倒退:& 是引用,* 是取消引用。

引用变量意味着访问变量的内存地址:

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

【讨论】:

等等,变量i的内存地址不是5,5是i的值。不是吗?内存地址应该类似于.. 0XA234948...我们不需要知道。 @dockbudu 正确。 i 的值为 5,内存地址将是我们无法控制的某个值(通常以十六进制表示)。【参考方案4】:

找到下面的解释:

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. 

结论:

    & [地址运算符] 用于引用。 * [star operator] 用于取消引用。

【讨论】:

【参考方案5】:

* 所在的上下文有时会混淆含义。

  // 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的上下文中,我们将使用dereferencer'*'来实际表示引用(地址),如果您看到来自编译器的错误消息说:'expecting char*' which is ask for a address.

在这种情况下,当 * 位于 type(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.


在每个块中,它复制传入的变量(如果有的话)(通过“()”中的参数)。在这些块中,对变量的更改是对该变量的副本,该变量使用相同的字母但位于不同的地址(与原始地址不同)。通过使用原始地址“引用”,我们可以使用 main 之外的块或 main 的子块内的块来更改变量。

【讨论】:

【参考方案6】:

参考

& 是引用运算符。它将内存地址引用到指针变量。

示例:

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.

【讨论】:

【参考方案7】:

被取消引用的指针的引用也和被指向的变量的地址相同。

解释:-

int var = 3; int *p;

p = &var;

所以, 假设 var 的地址是:ABCDE

那么,

p = ABCDE 和 &*p = ABCDE;

这意味着将 &* 放在一起,中性引用和取消引用。


在声明函数时,

函数的参数应该是指针,

在 main 方法中调用 this 函数的参数中应该使用 & 运算符。

这有点令人困惑。 但请记住 int *p = &var;和上面的指针声明一样也是正确的。

【讨论】:

如果要添加更多信息,请不要添加新答案,而是使用编辑按钮编辑原始答案,您应该保留此答案并删除“小版本”,您还应该编辑回答并格式化您的代码(在编辑器中选择并按下大括号)

以上是关于C中“引用”和“取消引用”的含义的主要内容,如果未能解决你的问题,请参考以下文章

linux C/C++中deferencedereferenced含义(解引用)

通过指针、强制转换和取消引用加载向量?

text 在C中取消引用指针

在 Python/ctypes 中的结构内取消引用 C 函数指针

在 C 中取消引用指向 0 的指针

C: Cppcheck : 可能的空点取消引用