最近我注意到在C语言中,对于以下声明:array
和&array
之间存在重要区别:
char array[] = {4, 8, 15, 16, 23, 42};
前者是指向字符的指针,而后者是指向包含6个字符的数组的指针。另外,值得注意的是,写作 a[b]
只是 *(a + b)
的语法糖。实际上,你可以写 2[array]
,这符合标准。
因此,我们可以利用这些信息来编写如下代码:
char last_element = (&array)[1][-1];
&array
的大小为6个字符,因此(&array)[1])
是指向数组右侧的字符指针。通过查看[-1]
,因此我正在访问最后一个元素。
有了这个,例如我可以交换整个数组:
void swap(char *a, char *b) { *a ^= *b; *b ^= *a; *a ^= *b; }
int main() {
char u[] = {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < sizeof(u) / 2; i++)
swap(&u[i], &(&u)[1][-i - 1]);
}
这种通过数组末尾访问数组的方法是否存在缺陷?
sizeof
表达式。 - Jensarray
]是指向char的指针”是错误的。这是前两段中唯一的、单一的错误,但是这里有一个小问题:array
确实是由6个char
组成的整个数组。不是指向数组的指针,也不是指向元素的指针,而是整个数组。这就是为什么sizeof(array)
可以返回数组的大小。然而,在sizeof
和&
运算符之外,数组在所有其他上下文中都会衰变成为指向其第一个元素的指针。这就是为什么它看起来像是一个指针,但实际上并不是。 - cmaster - reinstate monica