【问题标题】:A pathological way of passing an array: by reference to the first element传递数组的一种病态方式:通过引用第一个元素
【发布时间】:2017-04-18 02:26:48
【问题描述】:

似乎可以通过引用第一个元素来传递数组:

void passMe(int& firstElement)
{
    int* p=&firstElement;
    cout << p[0] << p[1];
}

主程序:

int hat[]={ 5,2,8 };
passMe(hat[0]);

通常,我会使用void passMe(int* myArray)void passMe(int[] myArray) 来代替上述函数定义。但是上述方法会引起任何问题吗?如果没有别的,知道答案会让我更好地理解这里的事情。

【问题讨论】:

  • 请注意,C 和 C++ 是不同的语言。这显然是一个 C++ 问题,因此请仅使用相关标签。
  • 一个问题是你不知道passMe函数内部有多少元素组成数组。
  • @kaylum 感谢您的提醒。是的,cout 仅适用于 C++,但我标记了 C,因为在我看来,问题的要点同样适用于两者。
  • @FreshAir -- 两者同样适用 -- 不,不是。 C中没有引用参数之类的东西。
  • C 没有通过引用。 int&amp; firstElement 不是有效的 C。如果应用于 C,这个问题毫无意义。

标签: c++ arrays parameter-passing


【解决方案1】:

就语言律师和编译器而言,这很好。主要问题将与人类程序员(包括您自己的未来版本)有关。当您的标准 C++ 程序员在程序中看到这一点时:

void passMe(int& firstElement);  // function declaration (in a .h file)

int hat[]={ 5,2,8 };
passMe(hat[0]);

他预计 passMe() 可能会读取和/或修改 hat[0]。他绝对不会期望 passMe() 可能会读取和/或修改 hat[1]。当他最终弄清楚你在做什么时,他会对你通过不必要的“聪明”代码误导他感到非常不满。 :)

此外,如果另一个程序员(他不知道你的把戏)试图从他自己的代码中调用你的函数,在只看到标头中的函数声明之后,他可能会尝试做这样的事情:

int cane = 5;
passMe(cane);

...当 passMe() 尝试在 cane 之后引用数组中的第二项时,这将直接导致运行时神秘的未定义行为,这实际上并不存在,因为 cane 实际上不在数组中。

【讨论】:

  • 同样的逻辑可以应用于将指针传递给数组的第一个元素。唯一的区别是,与传递参考相比,出于各种历史原因,我们更愿意期待这一点。
  • operator= 的许多实现中,您很容易看到正在使用的引用地址的一个实例是对自赋值的测试,即if (this != &amp;rhs)
  • @PaulMcKenzie 这是真的——我认为提问者的例子中值得怀疑的部分不是从引用中推导指针,而是在之后将指针算术应用于该指针(即传入的值将是数组的一部分的假设,尽管函数的签名是许多/大多数程序员会假设的一个,这会排除这种假设)
猜你喜欢
  • 2020-05-28
  • 2017-03-20
  • 2016-04-09
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
相关资源
最近更新 更多