【问题标题】:Arrays passed by reference by default?默认情况下通过引用传递的数组?
【发布时间】:2020-05-25 14:40:12
【问题描述】:

我正在阅读一本 C++ 书,上面写着:

C++ 通过引用将数组传递给函数——被调用的函数可以修改调用者原始数组中的元素值。

指的是这样的情况:

int hourlyTemperatures[ 24 ]; 
modifyArray( hourlyTemperatures, 24 );

然而,这里是普通的 C 数组指针,对吧?没有使用 C++“引用”技术,传递的是 值指针,在这种情况下,是指向数组第一个元素的指针。最终结果是该函数确实可以访问完整的原始数组,就像引用一样,但这实际上并不是按引用传递,对吧?

来自 Prentice Hall 的这本书:

【问题讨论】:

  • 通过引用传递数组需要int (&)[24](或std::array<int, 24> &)类型的参数。
  • 是的,你是对的,这本书是错误的,它在谈论 C 数组如何作为指针传递,并且混淆了“按引用传递”和“传递指针”按价值”。
  • ^^ 同意。坏书就是坏书。
  • 不是术语错误,而是已经过时了。 20 年前没有区别。
  • @HotLicks:即使当时没有错,现在也了。

标签: c++ c


【解决方案1】:

确实,当您将数组传递给函数时,您实际上是在按值传递指针。但是,我觉得对于刚学习 C++ 的人来说,他们根本不必担心指针。他们了解到您可以通过值或引用函数来传递变量。

按值表示函数中变量的更改不会影响调用函数中的原始值。

通过引用意味着如果函数更改了变量的值,那么这些更改将在原始调用函数中看到。

当数组是函数的参数(没有 const 关键字)时,对数组中的值所做的任何更改都将在原始调用函数中看到。因此,我们说数组默认是通过引用传递的。这避免了必须解释哪些指针在传递静态声明的数组时实际上并不相关,但它让人们知道,如果他们在被调用函数中弄乱了数组中的值,这些更改将在调用函数中持续存在.

我在一所一流的工程学校教授“第一门课程”计算机科学 C++ 课程(我们的编程团队将参加今年在俄罗斯举行的世界总决赛)。班上大约 90% 的人实际上并不是计算机相关专业(主要是机械工程师)。上面的材料足以让他们混淆,而不必解释指针是什么。这就是为什么那本书和其他人提到数组是通过引用传递的,因为许多阅读这些书的人只需要“刚好够”的 C++ 就可以通过,而不必学习每一个细节。那些真正想编程的人应该毫无问题地过渡到数组实际上是通过指针传递的事实。

只是我的意见。

【讨论】:

  • 我同意。可以说,“通过引用传递”的部分含义是“隐式传递指向参数的指针而不是复制它的值”,这正是你将数组传递给 C 中的函数时发生的情况。大约是唯一一次你可以实际检测不同之处在于您是否将参数用作 sizeof 的参数,或者是否对它使用算术(如果它是一个数组,这当然是无效的)。因此,除了一些不起眼的小细节外,C 数组可以认为是通过引用传递的。
【解决方案2】:

你是对的。该措辞非常令人困惑,并且使用的“引用”含义与与同名 C++ 功能相关的术语 reference 不同。相反,它讨论的是数组名称衰减为指针的方式——实际上你根本不会像这样“传递一个数组”!

在“过去”中,“引用”的使用方式与“句柄”相同——这是一个抽象术语,表示在不支持它的语言中使用间接来伪造引用语义.但是,C++ 确实支持它称为references的东西;因此,在谈论 C++ 时,我们倾向于不使用“句柄”意义上的“引用”(显然 Deitel ∉ “我们”)。

推荐阅读:

任何其他 C++ 书籍要非常小心!尽管在生活的大多数领域中,如果我认为包含在上述两个特定列表中是一本书被认为是“好”的明确先决条件,那将是疯狂的,但有足够多的危险不正确的 C++ 文本那里(例如您引用的文本),这对于我们的语言新手来说是一个足够大的问题,在 C++ 书籍的世界中,它实际上是一个很好的经验法则。

【讨论】:

  • +1,感谢您抽出宝贵时间就“已完成”问题写出更好的答案
  • @Potatoswatter:直到我得到 my 说 ;) ;)
  • 谢谢;切换接受的答案,因为附加资源非常有用。
【解决方案3】:

总结我的评论,你是绝对正确的!

这本书在选择行话方面是错误的。它试图谈论arrays decaying to C pointers。它将按值传递此指针称为按引用传递,这是错误的。

这是一个很常见的误解,我相信我也是这样被教导的(将指针作为值传递 == 通过引用传递)。这在 C++ 引用和按引用传递方面是完全错误的。

如果这是正确的,I wouldn't be able to do this..

void ModifyMyArray(int *array){
   int oops[4]= {0};
   array = oops;

   array[2] = 1;
}
...
int MyArray[4] = {1,3,5,7};

ModifyMyArray(MyArray);

类似于 Java 中的这个问题 - Is Java "pass-by-reference" or "pass-by-value"?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 2016-05-25
    • 2012-05-03
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多