--------
1.言论:"数组/函数 名是指针" or "数组/函数 是指针"
--------
---
这里"是"的含义很明确(保险起见这里还是说明一下这个"基本"词语的含义).百度的结果,这里"是"的意思应当为"表示解释或分类".鉴于百度解释不令人满意,楼主于是在维基百科中找到"是"对应的英语中"be"的解释.维基百科中"Copula"(系动词)的部分解释如下:
Predicates formed using a copula may express identity: that the two noun phrases (subject and complement) have the same referent or express an identical concept.
They may also express membership of a class or a subset relationship.
楼主的翻译:由系动词组成的谓语可能表达 身份/同一性[1]:即主语和补语/表语[2]有相同的指称或表达相同的概念.
它们也可表达种类关系或子集关系.
[1]: 此处楼主觉得翻译不恰当,汉语中难以找到完全合适的词.
[2]: 国外说法基本是系动词后接complement即补语,而国内的对应说法是表语.而楼主曾翻过牛津词典并未找出表语对应的英文单词.不过倒是有一个相关的 "Predicative adjectives"表语形容词,此处暂不表.总之此处的"补语"意即"表语".
举例:左值引用是引用.(引用分为左值引用和右值引用,此处"是"表示分类.)
---
既然涉及到"数组名",那么就要看看"名"的意思."名称"对应的英文是name,这是C++中定义好了的术语.
下面引用C++标准草案N4594,第三章Basic concepts:
An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack.
A name is a use of an identifier (2.10), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1).
翻译:一个实体是一个值,对象,引用,函数,枚举,类型,类成员,位域,模板,模板特化,名称空间,或参数包.
一个名称是对表示一个实体或标签的一个 identifier, operator-function-id, literal-operator-id, conversion-function-id ,或template-id [3]的使用.
[3]: 文法元素不进行翻译.
此处结论很明显,"名称"不是"实体".那么"数组/函数名"自然不是作为实体(具体说是object)的"指针"了.
---
先挑容易的下手.此处先说明为何"函数"不是"指针".
上文讲过"指针"是object,此处顺便翻一翻object的定义. N4594 1.8 The C++ object model:
An object is a region of storage. [ Note: A function is not an object, regardless of whether or not it occupies storage in the way that objects do. — end note ]
此处已明确说明,函数不是object,而根据定义指针是object,结果很明显,函数不可能是指针.
"函数"有些时候像是指针,是因为有一个function-to-pointer conversion.
N4594 4.3:
An lvalue of function type T can be converted to a prvalue of type “pointer to T”. The result is a pointer to the function
函数左值可以隐式转换为一个指向该函数的指针纯右值.
于是下面的代码就是合法的:
void f();
void (* p)()=f;
函数f隐式转换为指针,但函数f不是指针.
---
下面我说明为何"数组"不是"指针".
首先,贴出标准草案N4594 3.9.2 Compound types 的一部分:
Compound types can be constructed in the following ways:
(1.1) — arrays of objects of a given type;
(1.2) — functions, which have parameters of given types and return void or references or objects of a given type;
(1.3) — pointers to cv void or objects or functions (including static members of classes) of a given type;
...
从这段可以看出Compound type至少分为三类,至少有 array type,function type和pointer type. array和pointer在 C++中可以算的并列的概念,怎么竟然说其中一个"是"另一个?
罪魁祸首当属 array-to-pointer conversion.
N4594 4.2:
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.
数组左值或右值可被转换到指向数组首元素的指针纯右值.
于是下面的代码是合法的:
int a[5];
int * p = a;
但终究,转换成和本来就是还是有区别的.
有人可能会觉得,纠结这些概念没必要.好,那么以后用C++用得多了,这样的人就会突然发现一些深坑.
比如,之前提及的转换不是总会进行.在一些上下文中,期望得到一个左值,此时到指针的转换就不会进行,因为转换后得到的是一个纯右值.如:
template <class T>
void f(T& t);
int a[5];
f(a);
此处调用f,其中的T的类型为int [5]. 不错,没有到指针的转换,数组就是数组,不是别的什么乱七八糟的玩意.
另外一个导致数组像指针的原因是,数组类型无法直接作为函数的参数类型和返回值类型.请看,N4594 8.3.5:
After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”.
此处明确说明,数组类型或函数类型被调整为指针类型,这再次证明数组或函数不是指针.只是C++的一些规定让它们有时候看起来**像**指针.而当遇上引用,它们可能就不会再像指针了.