[英]What's the difference between * and & in C?
我正在学习 C,但我仍然不确定我是否理解&
和*
之间的区别。
请允许我尝试解释一下:
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
我得到了这些,但后来变得混乱。
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
所以, funct(*a)
和funct(&a)
都是正确的,对吧? 有什么不同?
*
和&
作为类型修饰符int i
声明一个 int。int* p
声明一个指向int 的指针。int& r = i
声明对 int 的引用,并初始化它以引用i
。int& r;
不可能。相似地:
void foo(int i)
声明了一个采用 int 的函数(按值,即作为副本)。void foo(int* p)
声明了一个函数,它带有一个指向 int 的指针。void foo(int& r)
声明了一个通过引用获取 int 的函数。 (仅限 C++)*
和&
作为运算符foo(i)
调用foo(int)
。 该参数作为副本传递。foo(*p)
解引用整型指针p
和呼叫foo(int)
与INT由指向p
。foo(&i)
获取 int i
的地址并使用该地址调用foo(int*)
。( tl;dr )总之,取决于上下文:
*
可以是解引用运算符或指针声明语法的一部分。
&
可以是地址运算符或(在 C++ 中)引用声明语法的一部分。
请注意, *
也可能是乘法运算符,而&
也可能是按位 AND 运算符。
funct(int a)
创建一个副本
funct(int* a)
将指向 int 的指针作为输入。 但是会复制指针。
funct(int& a)
采用 int,但通过引用。 a 现在与给出的 int 完全相同。 不是副本。 不是指针。
最初在 C 中有指针而没有引用。 很多时候,尽管我们只想访问一个值而不复制它,而且我们传递的是地址而不是实际值的事实是一个不重要的细节。
C++ 引入了引用来抽象掉指针的管道。 如果你想在 C++ 中“显示”一个函数的值,那么引用是可取的。 该函数保证引用不为空,并且可以像访问值本身一样访问它。 指针对于其他目的仍然是必要的,例如,您可以“重新瞄准”指针或使用指针delete
,但不能使用引用来执行此操作。
它们的功能确实有重叠,如果没有一点历史,您应该会混淆我们两者都有。
因此,您直接问题的答案是,通常没有区别。 也就是说,如果您希望函数能够检查指针是否为空, f(int*)
会很有用。 如果您使用 C,那么指针是唯一的选择。
*
的含义取决于上下文。 在数据或函数参数声明中,它是数据类型限定符,而不是运算符int*
本身就是数据类型。 出于这个原因,编写以下内容可能很有用:
int* x ;
而不是:
int *x ;
它们是相同的,但第一种形式强调*
是类型名称的一部分,并在视觉上将其与作为解引用运算符的用法区分开来。
当应用于实例化的指针变量时,它是解引用运算符,并产生指向的值。
&
在 C 中只是一个运算符,它产生一个对象的地址(或指向)。 它不能在声明中使用。 在 C++ 中,它是引用的类型限定符,类似于指针,但具有更多限制性行为,因此通常更安全。
您在此处的评论中的建议:
funct(&a) // Sends an address of a pointer
是不正确的。 地址a
通过; 这只会是“指向的地址”是a
本身就是一个指针。 指针是地址。 指向int
的指针的地址类型将是int**
(指向指针的指针)。
也许有必要解释一下指针和值变量的基本原理? 指针描述变量在内存中的位置,而值描述内存位置的内容。
<typename>
*
是指向<typename>
数据类型的指针。&
* <value-variable>
产生的地址或位置<variable>
(即,指针<variable>
),*
* <pointer-variable>
取消引用一个指针以产生该指针表示的地址处的值。所以举个例子:
int a = 10 ;
int* pa = &a ;
然后
*pa == 10
void funct(int &a)
声明了一个接受引用的函数。 引用在概念上是一个指针,因为函数可以修改传入的变量,但在语法上像值一样使用(因此您不必一直取消引用来使用它)。
当您执行 func(&a) 时,它被称为“按引用调用”,这意味着您的参数“a”实际上可以在函数内修改,并且所做的任何更改对调用程序都是可见的。 如果要从函数返回多个值,这是一种有用的方法,例如:
int twoValues(int &x)
{
int y = x * 2;
x = x + 10;
return y;
}
现在,如果您像这样从主程序调用此函数:
int A, B;
B = 5;
A = twoValues(B);
这将导致:
A holding the value 10 (which is 5 * 2)
and B will hold the value 15 (which is 5 + 10).
如果您在函数签名中没有 & 符号,则您对传递给函数“twoValues”的参数所做的任何更改都只会在该函数内部可见,但就调用程序(例如 main)而言,它们将是相同的。
现在,当您想要传递值数组或列表时,调用带有指针参数的函数是最有用的。 例子:
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);
}
请注意, size_of_list 参数只是您要传递的数组中的元素数(而不是以字节为单位的大小)。
我希望这有帮助。
C++在很多方面都不同于c,引用是其中的一部分。
在 C++ 上下文方面:
void funct(int *a) // a 被声明为一个指针 这与 c 中指针的使用相关。所以,你可以将这个特性与 c 的特性进行比较。
void funct(int &a) // a 现在只接收指针(地址) 这将导致 c++ 中的引用用法……你不能将 this 与 c 的引用关联起来。
这是一个很好的问答,澄清了这两者之间的差异。 C++中的指针变量和引用变量有什么区别?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.