呃,竟然可以编译通过

文摘   2024-09-24 12:06   北京  

你好,我是雨乐~

今天聊一个有趣的概念Arr[i]i[Arr]等同。

作为开发人员,如果要访问数组元素,往往采用下标的方式即Arr[i]来获取该位置的数据,嗯,有趣的是,我们也可以使用i[Arr]进行访问。

也就是说:

int Arr[3] = {123};

std::cout << "value = " << Arr[2] << std::endl;

int Arr[3] = {123};

std::cout << "value = " << 2[Arr] << std::endl;

等同。即2[Arr] 也会正确输出 3,证明它与 Arr[2] 是等价的。这是因为数组下标运算符 [] 在语法上是对称的,不论是 Arr[i] 还是 i[Arr],它们都可以被解释为相同的内存地址计算和解引用操作。因此,2[Arr] 在语法上也合法并能够正常编译和执行。

语义等价性

在前面的示例代码中,2[Arr] 也会正确输出 3,证明它与 Arr[2] 是等价的。这是因为数组下标运算符 [] 在语法上是对称的,不论是 Arr[i] 还是 i[Arr],它们都可以被解释为相同的内存地址计算和解引用操作。因此,2[Arr] 在语法上也合法并能够正常编译和执行。

基于数组下标运算符的定义,我们可以将 Arr[i] 重新排列成以下形式:

Arr[i] = *(Arr + i)

由于 *(Arr + i) 是数组的第 i 个元素,在 C++ 和 C 中,数组下标运算符的定义也可以被看作:

i[Arr] = *(Arr + i)

这表明 i[Arr] 与 Arr[i] 在功能上是等价的。它们都通过将数组 Arr 的基地址加上索引 i,然后解引用得到相应的值。加法的交换律保证了 Arr + i 和 i + Arr 在内存地址计算上是等效的。

即两个表达式**(Arr + i)(i + Arr)最终都指向数组中的相同内存地址**

可读性

尽管 2[Arr] 可以编译通过,但在实际编程中,使用 Arr[i] 是更常见的做法。原因包括:

1.可读性Arr[i] 更符合直观的数组访问语义,使代码更易于阅读和理解。2.一致性:大多数程序员和代码风格指南推荐使用 Arr[i],因为它更清晰、更具语义性。

2[Arr] 更像是一个数学上的趣味性表达或用于测试编译器的工具。实际编程中很少会用到这种写法。理解其等价性有助于深入掌握数组下标运算符的工作原理,但建议在代码中坚持使用更为直观的 Arr[i]

总结

Arr[i] 和 i[Arr] 在 C++ 和 C 中是等价的,2[Arr] 也是合法的并且能够编译通过。这种等价性源于数组下标运算符的定义和加法的交换律。尽管 2[Arr] 可以成功编译,但 Arr[i] 是更常见的写法,因为它更符合直观的语义。理解这些细节有助于更好地掌握 C++ 和 C 中的数组操作。

以上~~

如果对本文有异议或者有其他技术问题,可以加微信交流:

推荐阅读  点击标题可跳转

1、for循环的演变:从C++03到C++20

2、性能大杀器:与std::endl的较量

3、性能大杀器:智能指针的资源管理


雨乐聊编程
毕业于中国科学技术大学,现任某互联网公司高级技术专家一职。本公众号专注于技术交流,分享日常有意思的技术点、线上问题等,欢迎关注