考虑以下简单示例计算数组的长度:
#include <iostream>
int a[] = {1, 2, 4};
int main(){ std::cout << sizeof(a)/sizeof(a[0]) << std::endl; }
标准N4296::8.3.4/7 [dcl.array]
如果E是秩i×j×的n维阵列。 。 。×k,然后E出现 在 的表达式中,受到数组到指针的转换 (4.2)转换为指向(n-1)维数组的指针 等级j×。 。 。×K
N4296::4.2/1 [conv.array]
“N T数组”或“未知数组的数组”的左值或右值 T“可以转换为”指向T“的prvalue类型。结果 是指向数组第一个元素的指针。
那么转换的主题是什么表达式?看起来未评估的操作数不是主题。
答案 0 :(得分:3)
我知道以下表达式,其中数组未转换/衰减为指针。
sizeof
运算符中使用时:sizeof(array)
&array
int (&ref)[3] = array;
。decltype
中使用时:decltype(array)
答案 1 :(得分:2)
我不知道是否有人可以将所有规则排除在首位,因此社区维基可能是合适的。
数组到指针的转换发生在以下上下文中。所有引用都是针对C ++ 11标准的。
+
运算符([expr.unary.op] / 7)+
运算符([expr.add] / 1)-
运算符([expr.add] / 2)在以下上下文中不会发生数组到指针的转换:
&
运算符([expr.unary.op] / 3)sizeof
([expr.sizeof] / 4) 1 这包括将T
数组传递给期望 cv T*
, cv的函数的情况 void*
或bool
,当用户定义的转换需要其中一种类型时,等。
2 这包括在bool
语句中出现的if
的上下文转换等。
答案 2 :(得分:1)
我工作的经验法则是&#34;在表达式的任何部分中产生一个值存储在指针中但不能存储在数组中的值结果&#34;。
所以,例如;
array + 0
在执行添加之前将array
转换为指针,并给出一个指针结果。f(array)
在调用接受指针或数组(不是引用)的函数array
之前将f()
转换为指针。array[0]
不需要将array
转换为指针(但是
编译器是免费的,因为它对该表达式的结果没有影响。)sizeof array
不会将array
转换为指针(因为它没有
完全评估array
,只评估其大小)p = array
将array
转换为指针和该值
存储在p
我确定在某些情况下我错过了,但这个简单的规则运作得相当好。当然,它是基于对表达式的理解.....
答案 3 :(得分:-2)
在您的示例代码中,a[0]
与*(a + 0)
相同,因此需要进行数组到指针的转换。请参阅内置下标运算符部分here。