我正在阅读一本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(来自指针的值,又名直接指向变量)
指向int i的指针
因此,为了澄清,在示例中使用“refer”或“&amp; bar”实际上会创建一个新变量,该变量与int i
中传递的foo(int& bar)
重复。
而不是包含50的新&bar
值,它将具有int i
的内存地址。
TL; DR
foo(int bar)
收到变量foo(int* bar)
收到变量的“值”,如果更改,它将更改调用方法中的变量。foo(int& bar)
接收变量的指针/内存地址。我希望其他人认为这和我一样有用,谢谢大家!
答案 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
将返回i
和bar
的值50
的地址。 References themselves don't have their own addresses
答案 3 :(得分:0)
我正在阅读一本c ++书籍/指南,但指针和参考文献对我来说似乎有点模糊
如果您尝试搜索,您会找到plenty of explanations for this,但这是我的尝试。
pointer是一个变量,通过指向它来告诉您在哪里找到另一个变量。指针实际上只是一个与另一个变量的内存中的地址相对应的数字。地址的示例是输出中的0018FC30和0018FD04。
reference是变量的别名(另一个名称)。如果您有一个变量a
并且为其创建了引用b
,b
将成为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
,这会要求编译器确保不会意外修改该值。您可以将它与引用和指针一起使用。
挑选引用与指针大部分时间都是编码风格。最重要的是保持一致,因为一直查找函数定义以查看您是否曾经使用过一次指针或引用,这很烦人。