gpt4 book ai didi

c++ - 按名称调用(正常顺序评估)

转载 作者:行者123 更新时间:2023-11-28 02:50:42 25 4
gpt4 key购买 nike

我在下面有以下代码(类似 C 的语言)。我知道如何跟踪是否使用了按值传递或按引用传递,但也有按名称调用机制。任何人都可以指导我如何跟踪按名称调用吗?

int x=12,y=10;
void tswap(int pa, int pb) {
int tmp;
tmp=pa;
pa=pb;
pb=tmp;
x=x+pa;
x=x-pb;
y++;
printf("%d %d %d %d\n",pa,pb,x,y);
}
int main() {
int a=4;
tswap(x,a);
printf("%d %d %d\n",x,y,a);
tswap(++x,++y);
printf("%d %d %d\n",x,y,a);
return 0;
}

如果使用按值传递,输出将如下所示:

4 12 4 11

4 11 4

12 5 12 13

12 13 4

最佳答案

通常 C++ 使用按名称调用。按名称调用意味着函数的参数不会在函数调用时求值。它的行为就像参数将被替换到函数体中一样。

例子:

void foo(int a, int b) {
int s = 0;
for(int i=0; i<n; i++) {
s += b;
}
}

通常在 C++ 中,像 x = foo(3,bar(7)); 这样的示例表达式的行为类似于:

int tmp = bar(7);
x = foo(3,tmp);

bar 计算一次并将结果提供给函数 foo

使用按名称调用的语言可能会将 foo(3,bar(7)); 转换为

void foo() {
int s = 0;
for(int i=0; i<3; i++) {
s += bar(7);
}
}

在第一种情况下,函数 bar 将被计算一次,在第二种情况下,它将被计算 3 次。


但是,该规则也有异常(exception)。当函数声明已知时(例如,对于模板和内联),优化器可以使用它来生成优化代码。

例子:

inline unsigned foo(unsigned a, unsigned b) {
return a / b;
}

如果你调用 a = foo(x,2); 编译器会足够聪明,将其转换为 a = x/2; 然后转换为 a = x >> 1;.

甚至还有这个例子:

inline int foo(int a, int b) {
if(a == 0) return 0;
else return b;
}

现在编译器确实可以将 x = foo(0,bar(17)); 转换为 x = 0; 因此永远不会调用函数 bar。我认为只有在确保 bar 没有副作用的情况下才会进行这种优化。


虽然 C++ 不使用按名称调用,但您可以轻松地在 C++ 中使用该概念。只需为您的函数提供一个函数对象/指针。

例子:

template<typename F>
int foo(int a, F b) {
int s = 0;
for(int i=0; i<a; i++) {
s += b();
}
}

现在使用 foo(3, []() { static int i=0; return i++; }),其中第二个参数是 C++11 lambda,b 将分别被计算在您的代码中遇到它的时间。

关于c++ - 按名称调用(正常顺序评估),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23131456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com