什么是int&意思

时间:2011-01-07 19:12:44

标签: c++ pointers types

C ++问题,

我知道

int* foo(void)

foo将返回指向int类型的指针

怎么样

int &foo(void)

它返回什么?

非常感谢!

7 个答案:

答案 0 :(得分:35)

它将引用返回给int。引用类似于指针,但有一些重要的区别。我建议你阅读指针,引用,对象和原始数据类型之间的差异。

“有效的C ++”和“更有效的C ++”(均由Scott Meyers提供)对差异以及何时使用指针与引用有一些很好的描述。

编辑:有许多答案说“引用只是语法糖,更容易处理指针”。他们肯定是

请考虑以下代码:

int a = 3;
int b = 4;
int* pointerToA = &a;
int* pointerToB = &b;
int* p = pointerToA;
p = pointerToB;
printf("%d %d %d\n", a, b, *p); // Prints 3 4 4
int& referenceToA = a;
int& referenceToB = b;
int& r = referenceToA;
r = referenceToB;
printf("%d %d %d\n", a, b, r); // Prints 4 4 4

p = pointerToB更改p的值,即它现在指向不同的内存块。

r = referenceToB做了一些完全不同的事情:它将b的值分配给a的值。它确实更改rr仍然是对同一段记忆的引用。

差异很微妙但非常重要。

如果您仍然认为引用只是指针处理的语法糖,那么阅读Scott Meyers的书籍。他能比我更好地解释这种差异。

答案 1 :(得分:4)

这里要小心......你正在走C / C ++线。有一个非常明显的区别,但并不总是这样:

C ++ :这通常意味着参考。例如,考虑:

void func(int &x)
{
   x = 4;
}

void callfunc()
{
    int x = 7;
    func(x);
}

因此, C ++ 可以传递值或pass by reference

然而,

C 没有这样的传递参考功能。 &安培;表示“addressof”,是一种从变量表示指针的方法。但是,请考虑一下:

void func(int* x)
{
   *x = 4;
}

void callfunc()
{
    int x = 7;
    func(&x);
}

看似相似,但根本不同。您在 C 中正在做的是传递指针的副本。现在这些东西仍指向相同的内存区域,因此效果类似于指向内存的引用传递,但它不是传入的引用。它是对内存中一个点的引用。

试试这个(编译为C):

#include <stdio.h>

void addptr(int* x)
{
    printf("Add-ptr scope 1:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
    *x = *x + 7;
    x++;
    printf("Add-ptr scope 2:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
}

int main(int argc, char** argv)
{
    int a = 7;
    int *y = &a;
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    addptr(y);
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    return 0;

}

如果C通过引用传递,则由addptr更改的传入指针地址应反映在main中,但事实并非如此。指针仍然是价值观。

因此, C 通过引用机制进行任何传递。在C ++中,这是存在的,这就是&amp;在函数参数中表示等。

编辑:您可能想知道为什么我不能轻易地在C ++中进行此演示。这是因为我无法更改引用的地址。完全没有。来自t his quite good guide to references

  

如何重置make的引用   它指的是一个不同的对象?

     

没办法。

     

您无法将参考分开   指称。

     

与指针不同,一旦引用就是   绑定到一个对象,它不可能   “重新安置”到另一个对象。该   引用本身不是一个对象(它   没有身份;以地址为   引用为您提供地址   指称;记住:参考   是它的指示物。)

     

从这个意义上讲,参考文献是相似的   到一个const指针,如int * const   p(与指向const的指针相对)   例如int const * p)。但是,求求您   不要混淆引用   指针;他们与...非常不同   程序员的立场。

根据要求,返回参考资料:

#include <iostream>

using namespace std;

int& function(int f)
{
   f=f+3;
   return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

任何好的编译器都应该以某种形式给你这个警告信息:

exp.cpp:7:11:warning:引用与本地变量关联的堆栈内存       'f'返回

这是什么意思?好吧,我们知道函数参数被压入堆栈(注意:实际上不是在x64上,它们进入寄存器然后进入堆栈,但它们在x86上就是堆栈)并且这个警告说的是创建对这样的引用一个物体不是一个好主意,因为它不能保证留在原地。事实上,这只是运气。

那是什么给出的?试试这个修改过的版本:

#include <iostream>

using namespace std;

int& function(int& f)
{
    f=f+3;
    return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

运行此命令,您将看到两个值都得到更新。什么?好吧,他们都指的是同一件事,那件事正在编辑中。

答案 2 :(得分:1)

它返回对int变量的引用。

答案 3 :(得分:1)

来自阿尔弗雷德的评论

  

这就是文档所说的Texas instrument's TMS320C28x C/C++ compiler intrinsics,第122页,int&amp; __ byte(int,unsigned int),我猜它与PC不同 - Alfred Zhong

从手册:

  

int&amp; __ byte(int * array,unsigned int byte_index);

     

MOVB数组[byte_index] .LSB,src

     

C28x中最低的可加压单位是16位。   因此,通常您无法访问8位MOVB dst,数组[byte_index]。   LSB实体离开内存位置。此内在函数有助于从内存位置访问8位数量,并可按如下方式调用:

     

__ byte(array,5)= 10;
  b = __byte(array,20);

这只是意味着该函数返回对整数的引用,该整数的作用类似于8位数。因为值是引用修改将修改目标处的对象(就像MOVB)指令,而分配给b将复制(就像MOVB一样)到目标。

答案 4 :(得分:0)

这个问题根本不是C / C ++,因为C没有引用,只有指针。一个int&amp;是对int的引用。此外,您不需要void,它可以是int& foo();

答案 5 :(得分:0)

只是玩变量来显示意义

int i = 5;
int * pI = &i;
int & referenceToI = * pI;
referenceToI = 4; // now i == 4

编辑:引用只是一种语法糖,可以更轻松地处理指针。在汇编级别,编译器生成的代码返回给您一个地址指针

答案 6 :(得分:0)

https://isocpp.org/wiki/faq/references

此页面简洁明了!引用是别名。它是对象,只是换了个名字。以前的名称仍然有效。引用不是一个独立的对象。它是具有不同名称的对象。你不能对引用进行操作,因为它本身不是一个东西。它只是原始对象的别名。

就是这么简单。现在你可以很容易地想到它,而不是上面帖子中的一圈一圈。