【问题标题】:Why does C not have pass by address/reference without pointers?为什么 C 在没有指针的情况下没有按地址/引用传递?
【发布时间】:2013-02-26 05:40:44
【问题描述】:

考虑在 C++ 中这个使用指针传递的交换函数的简单测试。

#include <iostream>

using std::cout;
using std::endl;

void swap_ints(int *a, int *b)
{
   int temp = *a;
   *a = *b;
   *b = temp;
   return;
}

int main(void)
{
   int a = 1;
   int b = 0;
   cout << "a = " << a << "\t" << "b = " << b << "\n\n";
   swap_ints(&a, &b);
   cout << "a = " << a << "\t" << "b = " << b << endl;

   return 0;
}

这个程序是否比我通过地址传递使用更多的内存?比如在这个函数中声明:

void swap_ints(int &a, int &b)
{
   int temp = a;
   a = b;
   b = temp;
   return;
}

这个 C++ 函数的传递引用版本是否使用更少的内存,不需要创建指针变量?

C 不是和 C++ 一样具有这种“按引用传递”的能力吗?如果是这样,那为什么不呢,因为这意味着内存效率更高的代码,对吧?如果不是,那么 C 不采用这种能力的原因是什么。我想我没有考虑的是 C++ 可能会创建指针以在幕后实现此功能。这就是编译器实际上所做的——所以除了更简洁的代码之外,C++ 真的没有任何真正的优势吗?

【问题讨论】:

  • 引用指针,它们只是看起来不同。不过,它们在下面没有什么不同。 (除了它们不能为空。)
  • @Mehrdad 那么我的假设是正确的,除了让代码更整洁之外没有其他功能。
  • 不仅整洁,而且更安全,因为引用不能像指针那样为 NULL。但实际上,引用和指针在编译时通常会产生相同的机器代码。
  • “引用不能为空”是一个谬论。它的真正含义是,正式地,当您“传递空引用”时未定义的行为是在函数调用而不是在函数内部的某个位置调用的,但无论哪种方式,这都是以某种方式违反接口契约的问题最终导致未定义的行为。在实现(生成的机器代码)方面,完全相同的事情无论是指针还是引用都会发生。
  • 这是个人意见,虽然传递引用非常方便,但在某些方面我更喜欢 C 的仅指针方法。在调用函数时必须显式传入一个指针,并在函数体中显式取消引用它,有效地防止您忘记您正在通过引用传递一个变量(因此它可能会被修改),同样可以防止您无意中编写函数中的代码会在您不打算修改某些内容时进行修改。尽管可以通过在参数中添加const 修饰符来防止后者。

标签: c++ c memory-efficient


【解决方案1】:

唯一可以确定的方法是检查编译器为每个生成的代码,然后比较两者,看看你得到了什么。

也就是说,我会有点惊讶地看到真正的差异(至少在启用优化时),至少对于一个相当主流的编译器来说是这样。您可能会看到编译器在过去十年左右未更新的一些非常小的嵌入式系统上有所不同,但即使在那里,老实说也不太可能。

我还应该补充一点,在大多数情况下,我希望看到这样一个内联生成的琐碎函数的代码,因此根本就涉及函数调用或参数传递。在典型的情况下,它可能只需要进行几次加载和存储。

【讨论】:

    【解决方案2】:

    不要将代码中的变量计数与处理器使用的内存计数混淆。 C++ 有许多抽象层,它们隐藏了编译器的内部工作原理,以使事情变得更简单、更易于人类理解。

    按照设计,C 的抽象级别不如 C++。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 2021-07-16
      • 2022-01-21
      • 2014-01-19
      相关资源
      最近更新 更多