是否传递指针参数,在 C++ 中按值传递?

Posted

技术标签:

【中文标题】是否传递指针参数,在 C++ 中按值传递?【英文标题】:Is passing pointer argument, pass by value in C++? 【发布时间】:2011-05-24 12:17:05 【问题描述】:

在 C++ 中是否传递指针参数,按值传递?因为我看到对指针的任何更改都不会反映在方法之外。我通过取消引用指针所做的更改被反映了。

在这种情况下,使用指向指针的指针作为函数的参数来修改函数内的指针值是否可以接受/标准过程?

【问题讨论】:

指针是按值传递的,但是指针指向的对象可以被函数修改(取决于常量限定)。 【参考方案1】:

两者都是。

指针是按值传递的。这意味着指针变量的内容(指向的对象的地址)被复制。这意味着如果您更改函数体中指针的值,该更改将不会反映在仍指向旧对象的外部指针中。但是你可以改变指向的对象的值。

如果要将指针所做的更改反映到外部指针(使其指向其他内容),则需要两个间接级别(指向指针的指针)。调用函数时,通过在指针名称前放置 & 来完成。这是标准的 C 做事方式。

使用 C++ 时,使用引用优于使用指针(以后也使用指向指针的指针)。

对于为什么应该首选引用而不是指针,有几个原因:

引用比函数体中的指针引入的语法噪音更少 引用比指针保留更多信息,而不是对编译器有用

参考文献的缺点主要有:

它们打破了 C 的简单的按值传递规则,是什么让理解函数在参数方面的行为(它们会被改变吗?)变得不那么明显了。您还需要确定函数原型。但这并不比使用 C 时所需的多指针级别差。 C 不支持它们,当您编写的代码应该适用于 C 和 C++ 程序时,这可能是一个问题(但这不是最常见的情况)。

在指针指向的特定情况下,区别主要在于简单性,但使用引用也可以很容易地删除两个级别的指针并只传递一个引用而不是指针的指针。

【讨论】:

@Arafangion:我编辑了我的答案来解释为什么偏好应该优先于指针。 我想这是主观的——我更喜欢使用引用,因为我将空指针检查的责任转移给了调用者,而且我通常不关心 C 兼容性。但是,我不确定我是否接受了“您还需要函数原型以确保值不变”——这对于许多 C++ 类来说都是如此——它们本身可能是指针,可能会或可能不会共享数据。也就是说,我确实更喜欢按值传递并让类处理任何需要的指针,除非我返回应该立即设置的右值引用,无论如何,+1 @Arafangion:C 中的指针有效性检查位置也是调用约定的问题。我通常在调用者级别为内部函数执行它,并在 malloc 或外部入口点检查 lib。但实际上参考,检查变量不是 NULL 听起来和看起来很愚蠢。但是,当您传递某个自动数组的地址时,使用 C 语言时它也同样愚蠢,而被调用者代码所做的第一件事就是检查它是否为 NULL。 这些知识对我帮助很大。【参考方案2】:

如果您想潜在地更改指针本身,则可以使用指向指针的指针或对指针的引用。对于您最初的问题,从技术上讲,是的,所有参数都是按值传递的。

【讨论】:

"所有参数都按值传递" 不,按引用传递的参数不是按值传递的。【参考方案3】:

是的,就像在 C 中一样。

在这种情况下,使用指向指针的指针作为函数的参数来修改函数内的指针值是否可以接受/标准过程?

在什么情况下?你想要什么?您可以使用带有 & 修饰符的真实引用。

void func(type &ref);

【讨论】:

【参考方案4】:

我理解这里的困惑。 “按值传递”和“按引用传递”的概念并不那么清晰,即使它们看起来如此清晰。 请记住,计算机不知道这些概念,并且不会按照这些概念行事。 计算机不知道类型。因此,它不区分指针和值。 让我试着举例说明:

void func1(int x) //copy some value to local variable x (of type int)

   x = 5; //modify local variable. lost after function call


void func2(int *x) //copy some value to local variable x (of type int*)

   int a;
   x = &a; //modify local variable. lost after function call.


void func3(int *x) //copy some value to local variable x(of type int*)

   *x = 10; //x is local but *x is not! change is saved after function call!

func1 和 func2 是相同的。两者都修改局部变量。函数从堆栈中弹出后修改丢失。 func3 有能力改变另一个内存位置(一个不是函数本地的变量)。

基本上,每个函数调用都是“按值调用”。但是在指针类型的情况下,我们有办法改变内存中远程地址的内容。

【讨论】:

这真是太棒了,同时穿着。谢谢你的解释!【参考方案5】:

使用指针传递值 我会举例说明:

void f(int *ptr)

   cout<<*ptr;



int main ()

   int a=10;
   int *aptr=&a;
   f(aptr);
   return 0;
 

这里,在main函数中a是一个整数变量,内容为10,地址为00F8FB04(假设)。 aptr 是指向整数的指针,存放的是整数变量a的地址,所以aptr的内容就是整数变量a的地址,即00F8FB04。当我们将 aptr 作为函数参数传递时,只有 aptr 的内容(即地址)会复制到函数参数。 所以,ptr 会收到 aptr 内容的副本(即地址 00F8FB04)

【讨论】:

是的,传递给f的地址是一个副本。但是由于这是地址的副本,因此该地址中的内容可以通过 f 修改:)

以上是关于是否传递指针参数,在 C++ 中按值传递?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我要在 C 中按值传递函数参数?

在C ++中的继承上下文中按值传递对象[重复]

在lisp中按值传递参数

按引用传递或按值传递指针容器之间的区别

C++中的指针是按值传递的吗?

在 Ruby 中按值传递是啥意思? [复制]