C++ 初学者参考类型参数混淆

C++ 初学者参考类型参数混淆,c++,C++,对该函数的调用将是 foo(int &bar) { bar = 5; } 我认为函数参数本质上“获取”变量的内存地址,但不必在foo中取消引用,并且我将更改foobar的原始值,这对吗?在此之前,我的印象是,您必须传入这样一个内存地址: int foobar = 2; foo(foobar); foo(&foobar); void foo(int& bar) { bar = 5; } int foobar = 2; foo(foobar); v

对该函数的调用将是

foo(int &bar)
{
    bar = 5;
}
我认为函数参数本质上“获取”变量的内存地址,但不必在foo中取消引用,并且我将更改foobar的原始值,这对吗?在此之前,我的印象是,您必须传入这样一个内存地址:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}
然后使用foo中的变量,如下所示:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}

我认为这是错误的,对吗?我想,就像很多初学者一样,混淆源于这样一种想法:引用就像指针,它拥有一个内存地址,但它从来都不是一种真正的类型,是吗?只是一个操作符。

引用通常是通过底层指针实现的(尽管标准没有强制要求),但它们与指针完全不同。引用只是现有变量的新名称或别名。当你这样做的时候

*bar = 5;
您正在调用
foo
以使用变量
foobar
进行评估,因此本质上
foo
中的
bar
变成
foobar
。通常的编译器实现是实际实现以下代码:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}

引用通常是用底层指针实现的(尽管标准没有强制要求),但它们与指针完全不同。引用只是现有变量的新名称或别名。当你这样做的时候

*bar = 5;
您正在调用
foo
以使用变量
foobar
进行评估,因此本质上
foo
中的
bar
变成
foobar
。通常的编译器实现是实际实现以下代码:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}
如果您这样做:

void foo(int* bar)
{
    *bar = 5;
}

int foobar = 2;
foo(&foobar);
总的来说,x等于6。这是因为引用/别名(同一变量的不同名称)被传递到foo中。所以,函数foo中的bar和main中的x是相同的变量,相同的内存位置,等等

这不同于像这样的正常传球:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}
其中,bar是从main中的x复制的新复制构造值(注意,复制构造函数最好应用于非标量类型,但其思想是相同的)

最后,如果你做到了:

void foo(int bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}
对于foo的参数,它会说“我想要一个指向整数的指针”。大体上,我们取“堆栈变量x的地址”,它本质上与指向x的指针相同,我们将它传递到bar中。然后取消对条的引用并为其指定6将使main中的x也等于6:)

如果您这样做:

void foo(int* bar)
{
    *bar = 5;
}

int foobar = 2;
foo(&foobar);
总的来说,x等于6。这是因为引用/别名(同一变量的不同名称)被传递到foo中。所以,函数foo中的bar和main中的x是相同的变量,相同的内存位置,等等

这不同于像这样的正常传球:

int foobar = 2;

foo(foobar);
foo(&foobar);
void foo(int& bar)
{
    bar = 5;
}

int foobar = 2;
foo(foobar);
void foo(int& bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}
其中,bar是从main中的x复制的新复制构造值(注意,复制构造函数最好应用于非标量类型,但其思想是相同的)

最后,如果你做到了:

void foo(int bar) { bar = 6; }

int main() {
    int x = 3;
    foo(x);
}

对于foo的参数,它会说“我想要一个指向整数的指针”。大体上,我们取“堆栈变量x的地址”,它本质上与指向x的指针相同,我们将它传递到bar中。然后,将引用和分配给6,它将使X在主体中也等于6:(

<代码> fo(& bar){} <代码>不是一个适当的C++函数定义。确切的DUP。不完全,我不知道传递指针和传递作为引用的区别,而是如何使用‘引用变量’。”(&bar){}不是一个适当的C++函数定义。确切的DUP,不完全是,我不知道传递指针和传递作为参考的区别,而是如何使用“参考变量”。那么,仅仅是使用指针参数,它是更可接受的编码实践吗?@不,如果有什么,那么OP。假设。在语言中两者都有位置。那么,仅仅坚持指针参数是否更容易接受编码实践?@SirYakalot:不,如果有什么相反的话。在语言中两者都有位置。