*和&之间有什么区别?在C?

时间:2015-02-28 05:51:33

标签: c++ c pointers dereference

我正在学习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)都是正确的,对吧?有什么区别?

7 个答案:

答案 0 :(得分:15)

*&类型修饰符

  • int i声明一个int。
  • int* p向int。
  • 声明pointer
  • int& r = i向int声明reference,并将其初始化为引用i
    仅限 C ++。请注意,必须在初始化时分配引用,因此无法int& r;

类似地:

  • void foo(int i)声明一个带int的函数(按值,即作为副本)。
  • void foo(int* p)声明一个函数,它指向一个int。
  • void foo(int& r)声明一个通过引用获取int的函数。 (同样,仅限C ++)

*&运营商

  • foo(i)来电foo(int i)。该参数作为副本传递。
  • foo(*p)取消引用int指针p并使用foo(int i)指向的int调用p
  • foo(&i)获取int i的地址,并使用该地址调用foo(int* i)

tl; dr )总而言之,取决于具体情况:

答案 1 :(得分:6)

funct(int a) 

创建

的副本
funct(int* a) 

将指向int的指针作为输入。但是制作指针的副本。

funct(int& a)

采用int,但通过引用。 a现在与给出的int完全相同。不是副本。不是指针。

答案 2 :(得分:0)

void funct(int &a)声明一个reference的函数。引用在概念上是一个指针,因为函数可以修改传入的变量,但在语法上使用就像一个值(所以你不必一直使用它去引用它)

答案 3 :(得分:0)

C ++在很多方面与c不同,而引用也是其中的一部分。

就c ++上下文而言:

void funct(int * a)//声明为a指针 这与c..so中指针的使用相关,您可以将此功能与c。

进行比较

void funct(int& a)//现在只接收指针(地址) 这将导致c ++中的引用用法... 你无法将其与c ...

相提并论

这是一个很好的q& a澄清这两者之间的差异。 What are the differences between a pointer variable and a reference variable in C++?

答案 4 :(得分:0)

最初在C中有指针而没有引用。很多时候我们只是想在不复制它的情况下访问一个值,而且我们通过一个地址而不是实际值这一事实是一个不重要的细节。

C ++引入了抽象指针管道的引用。如果你想"显示" C ++中函数的值,然后引用是首选。该函数保证引用不为null,并且可以像访问值一样访问它。指针仍然是其他用途所必需的,例如,您可以重新瞄准"带指针的指针或delete,但您无法使用参考。

他们的功能 重叠,没有一点历史记录,应该让我们混淆我们两者。

所以直接问题的答案是,通常没有区别。也就是说,如果您希望函数能够检查指针是否为空,f(int*)会很有用。如果您正在使用C,那么指针是唯一的选择。

答案 5 :(得分:0)

当您执行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参数只是您传递的数组中的元素数(不是以字节为单位的大小)。

我希望这会有所帮助。

答案 6 :(得分:0)

*的含义取决于背景。在数据或函数参数声明中,它是数据类型限定符, 运算符 int*本身就是一种数据类型。出于这个原因,或许可以写一下:

int* x ;

而不是:

int *x ;

它们是相同的,但第一种形式强调*是类型名称的一部分,并在视觉上区别于用作解引用运算符。

当应用于实例化的指针变量时,它是取消引用运算符,并产生指向的值。

C中的

&只是一个运算符,它产生一个对象的地址(或指向的指针)。它不能用于声明中。在C ++中, 引用的类型限定符,它类似于指针,但具有更严格的行为,因此通常更安全。

您在评论中的建议:

funct(&a) // Sends an address of a pointer

不正确。 a的地址已通过;只有“指针的地址”是a本身就是一个指针。指针地址。指向<{em>}的地址类型int将是int**(指向指针的指针)。

也许有必要解释指针和值变量的基本原理? 指针描述变量内存中的位置,而描述内存位置的内容。

  • <typename> *是指向<typename>数据类型的指针。
  • & * <value-variable>生成 <variable> 的地址或位置(即指针 <variable> ),
  • * * <pointer-variable>取消引用指针,以获得指针所代表的地址处的值。

所以举个例子:

int a = 10 ;
int* pa = &a ; 

然后

*pa == 10