什么更有效:通过指针或值传递参数?

时间:2014-02-15 15:12:37

标签: c++ parameter-passing

什么更有效:通过指针或值调用?我认为它是由指针调用,因为传递指向变量的指针不会使用与创建变量副本一样多的内存。我错了吗?

main(){
   int a, b;
   a = 10;
   b = 5;
   gcf(&a, &b);
   return 0;
}
int gcf(int* c, int* d){
   int val1=*c;
   int val2=*d;
   //...
}

3 个答案:

答案 0 :(得分:10)

在几乎所有代码中,只要我们处理小/简单对象,复制对象的开销与将其作为指针或引用传递的开销相当小。

显然,如果我们在其中创建一个包含大量文本的std::string,相对于传递引用,复制它需要相当长的时间。

但是,编写代码时的主要对象是关注正确性。如果您有“大”对象,那么如果未修改该值,请使用const Type &val - 这样,您就不会意外地修改它。如果要修改对象,则需要使用引用或指针将更新返回给函数的调用者。

完全可以使用引用而不是使用值来使代码运行速度明显变慢。我曾经研究过一些我们正在研究的代码的性能,并找到了一个看起来像这样的函数:

void SomeClass::FindThing(int &thing)
{
    for(thing = 0; someVector[thing] != 42; thing++)
       ;
}

它看起来真的很无辜,但是因为thing的每次更新都意味着间接内存访问[至少在我们使用的编译器中,这当然不是“垃圾”],它需要花费很多时间在整个过程中[它也被称为必要的两倍]。

我把它重写为:

void SomeClass::FindThing(int &thing)
{
    for(int i = 0; someVector[i] != 42; i++)
       ;
    thing = i;
}

该功能的运行速度提高了约4倍。取出第二个不必要的调用,最终运行时间缩短了约30%。这是一个“字体基准”,这是“绘制字体到屏幕”中涉及的几十个功能中的一个。一个简单,无辜的功能可以对性能产生巨大的影响,这是多么可怕。

答案 1 :(得分:4)

对于小于指针大小的类型(例如int),传递值更有效 对于大于指针大小的类型(例如大多数结构或类实例),通过引用传递可能更有效(仅“可能”,因为除了传递参数的成本之外,可能构造对象,您需要花费成本每次使用时取消引用您的参数)。

有关按值传递与传递引用的更多详细信息,请参阅this question。有关引用与指针参数的更多详细信息,请参见that question

答案 2 :(得分:1)

在您的代码段示例

main(){
   int a, b;
   a = 10;
   b = 5;
}
int gcf(int* c, int* d){
   int rem;
   int val1=*c;
   int val2=*d;
   //...
}
如果你不打算改变它们,那么使用指针间接地将变量a和b传递给函数没有任何意义。在这种情况下,代码无效,因为要获得* c和* d的值,编译器将需要生成更多指令。

你说错了

  

将指针传递给变量不会使用尽可能多的内存   创建变量的副本。我错了吗?

通常指针等于或甚至大于int类型的大小。对于64位系统中的exaple,sizeof(int)可以等于4,而sizeof(int *)可以等于8。

当对象的大小远大于指针的大小时,通过指针(通常在C程序中)间接传递对象是有意义的。 在C ++而不是指针中,通常使用引用。

例如

#include <iostream>
#include <string>

inline void print_reverse( const std::string &s )
{
   std::cout << std::string( s.rbegin(), s.rend() ) << std::endl;
}

int main()
{
   std::string s( "Hello World" );

   print_reverse( s );
}

这里const std::string &s定义了对std :: string。

类型的对象的引用