繁体   English   中英

C 中的 * 和 & 有什么区别?

[英]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
    仅限 C++。 请注意,必须在初始化时分配引用,因此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 )总之,取决于上下文:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM