在C和C ++中通过index [array]访问数组

有些面试官出于某种原因喜欢问这个小技巧:


int arr[] = {1, 2, 3};

2[arr] = 5; // does this line compile?

assert(arr[2] == 5); // does this assertion fail?

据我了解,a[b]转换为,*(a + b)并且由于加法是可交换的,因此它们的顺序并不重要,2[a]确实如此*(2 + a),并且效果很好。


是否可以保证按C和/或C ++的规范工作?


慕哥9229398
浏览 642回答 3
3回答

波斯汪

是。6.5.2.1第1段(C99标准)描述了[]运算符的参数:其中一个表达式的类型应为“指向对象的指针type”,另一个表达式的类型应为整数,结果的类型应为“ type”。6.5.2.1第2段(增加了重点):表达式后跟方括号中的表达式[]是数组对象元素的下标名称。下标操作符的定义[] 是E1[E2]相同(*((E1)+(E2)))。由于适用于二进制+运算符的转换规则,如果if E1是一个数组对象(相当于一个指向数组对象的初始元素的指针)并且E2是一个整数,E1[E2]则将其指定为E2-th元素E1(从零开始计数)。它说没有什么要求参数的顺序[]是理智的。

精慕HU

通常,2[a]它与a[2]C 相同,并且保证在C和C ++中都是等效的(假定没有运算符重载),因为正如您所指的那样,它分别转换为*(2+a)或*(a+2)。因为加号运算符是可交换的,所以两种形式是等效的。尽管这些形式是等效的,但为了所有神圣的事情(以及将来的维护程序员),请相对于其他形式更喜欢“ a [2]”形式。PS,如果确实在面试中被问到此问题,请代表C / C ++社区进行确切的复仇,并确保您要求面试官列出所有三字母组合序列,作为您给出答案的前提。也许这会使他/她将来不再提出这样的问题(就实际编程而言毫无价值)。在奇怪的情况下,访问员实际上知道所有三个字母组合序列,您总是可以尝试对虚拟基类的销毁顺序提出质疑,就像虚拟思维与日常编程毫无关系一样。

www说

但在C ++中,您可以#define ARRAY_SIZE(a) (sizeof(a) / sizeof(0[a]))用作宏来查找无法(也不能使其)工作的数组大小std::vector以及[]操作符重载的类型-这无法防止int *a = /*something*/; ARRAY_SIZE(a)但对于任何事情都可以非常安全其他。(这是0[a]我见过的唯一有用的用法)
打开App,查看更多内容
随时随地看视频慕课网APP