【问题标题】:Is it true that when passing an argument to a function, it is like assigning the value to the parameter?是否真的将参数传递给函数时,就像将值分配给参数一样?
【发布时间】:2022-01-11 19:34:38
【问题描述】:

我是 C++ 新手,我在这里写伪代码:

void fn(a) {}
fn(b) 

假设在函数体fn中发生的是这个赋值是正确的

`a = b`

我知道我们可以传递引用/指针而不仅仅是值。我得到它。但它的核心仍然是 parameter = argument 的赋值,对吗?

我想知道:

  1. 是否有任何官方术语?
  2. 这个分配究竟是什么时候发生的,究竟是什么导致了这种情况发生?是编译器吗?

【问题讨论】:

  • 或多或少。不完全是赋值,更像是初始化。 (一)为了什么? “通过争论”听起来很正式吗? (2) 当然是编译器,还能是什么?它发生在函数被调用之前?
  • 如果没有最低限度的 validcompiling 代码,假设任何事情都不是真正“正确”的。也许您正在寻找术语"call by value" and "call by reference"。 C 中不存在引用调用;因此为什么双重标签(加上无效/不完整的代码)在这里特别成问题。
  • 除非询问两种语言之间的差异或交互,否则不要同时标记 C 和 C++。不同语言的答案可能不同。
  • 嘿,谢谢你的建议。我删除了c 标签。
  • @Joji 还需要一些编译代码。考虑这两个不同的函数,用一个值代替“a”,以及这可能如何影响答案和/或正在寻找的内容:void f(int x) { x = 2; }void g(int& x) { x = 2; }

标签: c++ parameter-passing function-parameter


【解决方案1】:

这有什么官方术语吗?

函数调用的官方语义在 C 标准的“函数调用”部分讨论。没有专门用于将值分配给参数的术语。

C++ 2017 草案 N4659 8.2.2 “函数调用” [expr.call] 4 说:

调用函数时,每个参数 (11.3.5) 都应使用其对应的参数初始化 (11.6, 15.8, 15.1)……

这个分配究竟是什么时候发生的,究竟是什么导致了这种情况发生?是编译器吗?

当调用函数时会发生这种情况。编译器负责生成代码,生成执行源代码语义(由 C++ 标准定义)的程序。

【讨论】:

  • 我能问一下“正在初始化”和像int a = b这样的赋值有什么区别吗?
  • @Joji: int a = b 是一个初始化。 a = b 是一个任务。我将把它留给 C++ 专家来讨论初始化和赋值之间的任何区别或相似之处。
  • 初始化是在创建对象时为对象赋予值的动作(或动作集)。赋值是改变对象值的动作。对于结构/类类型,初始化涉及调用构造函数,赋值涉及调用名为 operator=() 的成员函数。
  • 我明白了..似乎初始化基本上只是第一个任务。
【解决方案2】:

C++ 标准描述了一个执行环境、各种语句的结果和各种表达式的结果。编译器只需要生成在运行时生成结果的代码,就好像它在所描述的执行环境中运行一样。

就您的实际问题而言,这意味着在实际硬件上运行时,源代码中的函数调用不一定会转换为任何类型的调用或跳转指令。

例如,给定函数:

int sqr(int x, inty)
{
  return x*y;
}

编译器很可能只是就地计算这样的结果,而不执行任何类型的参数传递。但是你是否真的可以依赖这种行为是编译器实现者的一个细节。

话虽如此,在实际硬件上并且没有内联,函数调用的参数与任何其他变量初始化非常相似(想想复制而不是分配)。确切的细节(例如参数评估的顺序)由每个实现决定。

【讨论】:

  • 谢谢您的回复!如果只是变量初始化,不赋值怎么获取它的值呢?
猜你喜欢
  • 2013-10-05
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 2021-04-18
相关资源
最近更新 更多