C 中的 * 和 & 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28778625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between * and & in C?
提问by Cristian Ceron
I'm learning C and I'm still not sure if I understood the difference between &
and *
yet.
我正在学习 C,但我仍然不确定我是否理解了&
和之间的区别*
。
Allow me to try to explain it:
请允许我尝试解释一下:
int a; // Declares a variable
int *b; // Declares a pointer
int &c; // Not possible
a = 10;
b = &a; // b gets the address of a
*b = 20; // a now has the value 20
I got these, but then it becomes confusing.
我得到了这些,但后来变得混乱。
void funct(int a) // A declaration of a function, a is declared
void funct(int *a) // a is declared as a pointer
void funct(int &a) // a now receives only pointers (address)
funct(a) // Creates a copy of a
funct(*a) // Uses a pointer, can create a pointer of a pointer in some cases
funct(&a) // Sends an address of a pointer
So, both funct(*a)
and funct(&a)
are correct, right? What's the difference?
所以,funct(*a)
和funct(&a)
都是正确的,对吧?有什么不同?
回答by emlai
*
and &
as type modifiers
*
并&
作为类型修饰符
int i
declares an int.int* p
declares a pointerto an int.int& r = i
declares a referenceto an int, and initializes it to referencei
.
C++ only. Note that references must be assigned at initialization, thereforeint& r;
is not possible.
int i
声明一个 int。int* p
声明一个指向int的指针。int& r = i
声明对 int的引用,并将其初始化为 referencei
。
仅限 C++。请注意,必须在初始化时分配引用,因此int& r;
不可能。
Similarly:
相似地:
void foo(int i)
declares a function taking an int (by value, i.e. as a copy).void foo(int* p)
declares a function taking a pointer to an int.void foo(int& r)
declares a function taking an int by reference. (Again, C++ only)
void foo(int i)
声明一个采用 int 的函数(按值,即作为副本)。void foo(int* p)
声明一个函数,它带有一个指向 int 的指针。void foo(int& r)
声明一个通过引用获取 int 的函数。(同样,仅限 C++)
*
and &
as operators
*
和&
作为运营商
foo(i)
callsfoo(int i)
. The parameter is passed as a copy.foo(*p)
dereferences the int pointerp
and callsfoo(int i)
with the int pointed to byp
.foo(&i)
takes the address of the inti
and callsfoo(int* i)
with that address.
foo(i)
调用foo(int i)
。该参数作为副本传递。foo(*p)
取消引用 int 指针p
并foo(int i)
使用指向的 int 进行调用p
。foo(&i)
获取 int 的地址i
并foo(int* i)
使用该地址进行调用。
(tl;dr) So in conclusion, depending on the context:
(tl;dr)总之,取决于上下文:
*
can be either the dereference operatoror part of the pointer declaration syntax.&
can be either the address-of operatoror (in C++) part of the reference declaration syntax.Note that
*
may also be the multiplication operator, and&
may also be the bitwise AND operator.
*
可以是解引用运算符或指针声明语法的一部分。&
可以是地址运算符或(在 C++ 中)引用声明语法的一部分。注意 也
*
可能是乘法运算符,也&
可能是按位 AND 运算符。
回答by Michael LeVan
funct(int a)
Creates a copy of a
创建一个副本
funct(int* a)
Takes a pointer to an int as input. But makes a copy of the pointer.
将指向 int 的指针作为输入。但是会复制指针。
funct(int& a)
Takes an int, but by reference. a is now the exact same int that was given. Not a copy. Not a pointer.
采用 int,但通过引用。a 现在与给出的 int 完全相同。不是副本。不是指针。
回答by Praxeolitic
Originally in C there were pointers and no references. Very often though we just want to access a value without copying it and the fact that we're passing around an address and not the actual value is an unimportant detail.
最初在 C 中有指针而没有引用。很多时候,尽管我们只想访问一个值而不复制它,而且我们传递的是地址而不是实际值的事实是一个不重要的细节。
C++ introduced references to abstract away the plumbing of pointers. If you want to "show" a value to a function in C++ then references are preferable. The function is guaranteed that a reference is not null and can access it as if it were the value itself. Pointers are still necessary for other purposes, for example, you can "re-aim" a pointer or delete
with a pointer but you can't do so with a reference.
C++ 引入了引用来抽象掉指针的管道。如果你想在 C++ 中“显示”一个函数的值,那么引用是可取的。该函数保证引用不为空,并且可以像访问值本身一样访问它。指针对于其他目的仍然是必要的,例如,您可以“重新瞄准”指针或delete
使用指针,但不能使用引用来这样做。
Their functionality doesoverlap and without a bit of history it shouldconfuse you that we have both.
它们的功能确实有重叠,如果没有一点历史,您应该会混淆我们两者都有。
So the answer to your direct question is that very often there is no difference. That said, f(int*)
can be useful if you want the function to be able to check if the pointer is null. If you're using C then pointers are the only option.
因此,您直接问题的答案是,通常没有区别。也就是说,f(int*)
如果您希望函数能够检查指针是否为空,这将很有用。如果您使用 C,那么指针是唯一的选择。
回答by Clifford
The meaning of *
is dependent on context. When in a data or function argument declaration, it is a datatype qualifier, notan operatorint*
is a datatype in itself. For this reason it is useful perhaps to write:
的含义*
取决于上下文。当一个数据或功能参数声明,它是一种数据类型预选赛中,没有一个运营商int*
本身就是一种数据类型。出于这个原因,编写以下内容可能很有用:
int* x ;
rather than:
而不是:
int *x ;
They are identical, but the first form emphasises that it the *
is part of the type name, and visually distinguishes it from usage as dereference operator.
它们是相同的,但第一种形式强调它*
是类型名称的一部分,并在视觉上将其与作为解引用运算符的用法区分开来。
When applied to an instantiated pointer variable, it is the dereferenceoperator, and yields the the value pointed to.
当应用于实例化的指针变量时,它是解引用运算符,并产生指向的值。
&
in C is only an operator, it yields the address (or pointer to) of an object. It cannot be used in a declaration. In C++ it isa type qualifier for a referencewhich is similar to a pointer but has more restrictive behaviour and is therefore often safer.
&
在 C 中只是一个运算符,它产生对象的地址(或指向 的指针)。它不能在声明中使用。在 C++ 中,它是引用的类型限定符,类似于指针,但具有更多限制性行为,因此通常更安全。
Your suggestion in the comment here:
您在此处的评论中的建议:
funct(&a) // Sends an address of a pointer
is not correct. The address of a
is passed; that would only be "address of a pointer" is a
itself is a pointer. A pointer isan address. The type of an address of a pointerto int
would be int**
(a pointer to a pointer).
是不正确的。的地址a
被传递;那只会是“指针的地址”a
本身就是一个指针。指针是地址。类型的的指针的地址以int
将int**
(一个指针的指针)。
Perhaps it is necessary to explain the fundamentals of pointer and value variables? A pointerdescribes the locationin memory of a variable, while a valuedescribes the content of a memory location.
也许有必要解释一下指针和值变量的基本原理?甲指针描述所述位置中一个变量的存储器,而一个值描述的存储器位置的内容。
<typename>
*
is a pointer-to-<typename>
data type.&
*<value-variable>
yields the address or location of<variable>
(i.e. a pointer<variable>
),*
*<pointer-variable>
dereferences a pointer to yield the the value at the address represented by the pointer.
<typename>
*
是指向<typename>
数据类型的指针。&
*<value-variable>
产生<variable>
(即指针<variable>
)的地址或位置,*
*<pointer-variable>
取消引用一个指针以产生该指针表示的地址处的值。
So given for example:
所以举个例子:
int a = 10 ;
int* pa = &a ;
then
然后
*pa == 10
回答by MaYa
When you do func(&a) that's called a "call by reference" that means your parameter "a" can actually be modified within the function and any changes made will be visible to the calling program. This is a useful way if you want to return multiple values from a function for example:
当您执行 func(&a) 时,它被称为“按引用调用”,这意味着您的参数“a”实际上可以在函数内修改,并且所做的任何更改对调用程序都是可见的。如果要从函数返回多个值,这是一种有用的方法,例如:
int twoValues(int &x)
{
int y = x * 2;
x = x + 10;
return y;
}
now if you call this function from your main program like this:
现在,如果您像这样从主程序调用此函数:
int A, B;
B = 5;
A = twoValues(B);
This will result in:
这将导致:
A holding the value 10 (which is 5 * 2)
and B will hold the value 15 (which is 5 + 10).
If you didn't have the & sign in the function signature, any changes you make to the parameter passed to the function "twoValues" would only be visible inside that function but as far as the calling program (e.g. main) is concerned, they will be the same.
如果您在函数签名中没有 & 符号,则您对传递给函数“twoValues”的参数所做的任何更改都只会在该函数内部可见,但就调用程序(例如 main)而言,它们将是相同的。
Now calling a function with a pointer parameter is most useful when you want to pass an array of values or a list. Example:
现在,当您想要传递值数组或列表时,调用带有指针参数的函数是最有用的。例子:
float average ( int *list, int size_of_list)
{
float sum = 0;
for(int i = 0; i < size_of_list; i++)
{
sum += list[i];
}
return (sum/size_of_list);
}
note that the size_of_list parameter is simply the number of elements in the array you are passing (not size in bytes).
请注意, size_of_list 参数只是您要传递的数组中的元素数(而不是以字节为单位的大小)。
I hope this helps.
我希望这有帮助。
回答by tskuzzy
void funct(int &a)
declares a function that takes a reference. A reference is conceptually a pointer in that the function can modify the variable that's passed in, but is syntactically used like a value (so you don't have to de-reference it all the time to use it).
void funct(int &a)
声明一个接受引用的函数。引用在概念上是一个指针,因为函数可以修改传入的变量,但在语法上像值一样使用(因此您不必一直取消引用来使用它)。
回答by basav
C++ is different from c in many aspects and references is a part of it.
C++在很多方面都不同于c,引用是其中的一部分。
In terms of c++ context:
在 C++ 上下文方面:
void funct(int *a) // a is declared as a pointer This corelates to the use of pointers in c..so, you can compare this feature to that of c.
void funct(int *a) // a 被声明为一个指针 这与 c 中指针的使用相关。所以,你可以将这个特性与 c 的特性进行比较。
void funct(int &a) // a now receives only pointers (address) This would lead to the reference usage in c++... you cannot corelate this to that of c..
void funct(int &a) // a 现在只接收指针(地址) 这将导致 c++ 中的引用用法……你不能将 this 与 c 的引用关联起来。
Here is a good q&a clarifying differences between these two. What are the differences between a pointer variable and a reference variable in C++?
这是一个很好的问答,澄清了这两者之间的差异。 C++中的指针变量和引用变量有什么区别?