c ++ - 指针和引用:一个简单的例子

时间:2016-01-28 14:57:38

标签: c++

我正在阅读一本c ++书籍/指南,但指针和参考文献对我来说似乎有点模糊。这来自我自己作为C#程序员和c#mindset使用

  

foo(ref int x)和bar(out in y)

我编写的一小段代码用于显示内存位置和内存位置值,但我并不完全理解每个代码的含义,以及它在什么上下文中。

int main()
{
    int i = 50;
    foo(&i);
    cout << "\n\n" ;
    foo(i);
    getchar();
    return 0;
}

void foo(int& bar) // & refer
{
    cout << "refer";
    cout << "\n&bar = " << &bar;
    cout << "\nbar = " << bar;
}

void foo(int* bar)// * pointer
{
    cout << "prefer";
    cout << "\n&bar = " << &bar;
    cout << "\nbar = " << bar;
}

输出显示:

pointer
&bar = 0018FC30
bar = 0018FD04

refer
&bar = 0018FD04
bar = 50

什么&amp; *在每种情况下都意味着,它如何影响输出?

ofcourse,我已将所有必要的方法添加到.h文件中

阅读一些答案后更新

int i(来自指针的值,又名直接指向变量)

  • 的值为= 50
  • 的内存地址= 0018FD04

指向int i的指针

  • 的值为int i memory address = 0018FD04
  • 有自己的内存地址= 0018FC30

因此,为了澄清,在示例中使用“refer”或“&amp; bar”实际上会创建一个新变量,该变量与int i中传递的foo(int& bar)重复。

而不是包含50的新&bar值,它将具有int i的内存地址。

TL; DR

  • foo(int bar)收到变量
  • 的“值”
  • foo(int* bar)收到变量的“值”,如果更改,它将更改调用方法中的变量。
  • foo(int& bar)接收变量的指针/内存地址。

我希望其他人认为这和我一样有用,谢谢大家!

5 个答案:

答案 0 :(得分:0)

来自C#,指针可以被认为是类,而值更像结构 - 当你改变它们的成员时,你要么改变一个副本(在传递值的对象的情况下,这不是显示),改变你传递的同一个对象(在传递指针的情况下),或改变相同的值,包括对你已经传递的实际值的引用(在传递的情况下)参考)。换句话说,实现决定了它是如何传递的,而不是控制传递方式的对象声明。

对于每个方法标题,行为如下:

void foo(int& bar) // & refer

当您使用type& name传递时,您将通过引用传递,并且您传递的是等效的C#ref(或out,如果您没有给变量a有意义的价值开始)。即使您传递了一个值,对值的更改(包括更改值本身)也会反映在调用范围内。

void foo(int* bar)// * pointer

使用type* name传递对象时,您将指针传递给该对象。但是,您将指针作为值传递,因此虽然您可以更改成员(在int的情况下没有实际意义),但您可以更改值(bar )本身。再次像C#一样,这就像在不使用class / ref的情况下传递out对象一样 - 重新分配不会反映在调用范围内。

在代码中使用&

cout << "\n&bar = " << &bar;

在这种情况下,&"address-of" operator。每当你在代码中取&variable时,你就会获得该变量的内存地址 - 打印这个值会给你的变量存在于RAM中的十六进制地址,除了最技术的调试之外,它基本上都是乱码和样本案例。这也适用于指针 - 你可以使用指针的指针(指针的指针......无限的)。

答案 1 :(得分:0)

想象一下我们有:

int* a; // This holds memory addresses
a = new int;

cout << a; // This will print the memory address of your new int
cout << *a; // This will print the value at the memory address a is holding 
cout << &a; // This will print the memory address of the pointer variable.

如果声明一个将指针作为参数的函数,则应传递指针而不是静态变量。

我希望这对你有所帮助,即使只是一点点。

答案 2 :(得分:0)

好的,首先是指针:

void foo(int* bar)// * pointer
{
    cout << "prefer";
    cout << "\n&bar = " << &bar;
    cout << "\nbar = " << bar;
}

您正在使用

进行调用
int i = 50;
foo(&i);

在此上下文中,*bar将为50(获取int指针指向的值)。 &bar是创建的指针的地址(指针本身在内存中也需要一个位置)。 bar是指针指向的对象的地址(在这种情况下为i

参考案例:

void foo(int& bar) // & refer
{
    cout << "refer";
    cout << "\n&bar = " << &bar;
    cout << "\nbar = " << bar;
}

此处,bar会引用您在i中创建的main。在这种情况下,&bar将返回ibar的值50的地址。 References themselves don't have their own addresses

答案 3 :(得分:0)

  

我正在阅读一本c ++书籍/指南,但指针和参考文献对我来说似乎有点模糊

如果您尝试搜索,您会找到plenty of explanations for this,但这是我的尝试。

pointer是一个变量,通过指向它来告诉您在哪里找到另一个变量。指针实际上只是一个与另一个变量的内存中的地址相对应的数字。地址的示例是输出中的0018FC30和0018FD04。

reference是变量的别名(另一个名称)。如果您有一个变量a并且为其创建了引用bb将成为a的替代名称。 引用的值不是像指针那样的地址,它是它引用的值的值。 引用的兴趣在于,当您复制它们或传递它们时,您不会复制实际值(这可能很昂贵),您只是复制名称。

主要的可观察差异是你可以改变指针指向的内容(通过改变指针的值,因为它的值实际上只是一个地址),但是你不能改变引用引用的内容(在方式,它成为它所指的。)

  

什么&amp; *在每种情况下都意味着,它如何影响输出?

如果您有变量a,则表达式&a表示“取a的地址”。 这很有趣,因为如果你有一个变量的地址,你可以指针指向它。

*a可以被视为或多或少的逆操作,如果你有一个指针a*a意味着“取这个指针所指向的地址的值”。

您可以在任何有地址的地方使用&a。您甚至可以使用指针的地址来创建指向指针的指针!但是你只能在行为像指针的东西上使用*a,否则就没有意义。

答案 4 :(得分:0)

在C ++中,默认值是按值传递。因此,如果您有f(X x),则编译器将生成每次调用函数时复制类X的代码。如果X很大(如数组,字符串,地图或类似的东西),出于性能原因,您可能不需要副本。制作副本也意味着如果您修改了函数内的参数,则只需修改副本,以便在返回后不会显示。

现在要在函数外部显示内容,您必须修改调用者的实例。为此,您必须具有指针(*)或引用(&)到该实例。两者之间立即可见的区别在于您可以将指针与nullptr进行比较(对于引用来说它更棘手),对于指针,您必须使用->来访问它的成员,vs {{1对于引用,并且在调用时必须使用参数的地址来获取指针(.)。通常,您应该使用参数,其中参数永远不会是f(&global_x)。当缺少该参数调用函数是合理的时,您应该更喜欢指针。这些与C#ref或out相同。两者之间存在更微妙的差异,但只有在编写模板和库时它们才会变得明显。

如果要避免复制,但不想修改参数,则应使用nullptr,这会要求编译器确保不会意外修改该值。您可以将它与引用和指针一起使用。

挑选引用与指针大部分时间都是编码风格。最重要的是保持一致,因为一直查找函数定义以查看您是否曾经使用过一次指针或引用,这很烦人。