包含数组下标的表达式可以是标识符吗?
Is an expression including array subscripting can be an identifier?
int a[2][4] = {........};
在上面的代码中,a
是一个数组类型的标识符。但是我很好奇a[2]
,它是一个4个int元素的数组,是否也是一个标识符?
没有。标识符是例如变量或函数的名称。正如@WhozCraig 在评论中所写,它不仅是变量或函数。该术语来自语法分析器:
function ::= identifier '(' parameter ( ',' parameters )* ')'
在示例 a[2][4]
中,a
是一个标识符和一个值。 a[2]
和 a[2][4]
都是值,但不是标识符。它们也是左值,即您可以在赋值符号 =
:
左侧写 a
、a[2]
和 a[2][4]
a[2][4] = 100;
不,a[2]
是数组 对象 的一个元素。引用 C11
,章节 §6.5.2.1/2,数组下标
A postfix expression followed by an expression in square brackets []
is a subscripted
designation of an element of an array object.
从 §6.4.2.1 添加 标识符
An identifier is a sequence of nondigit characters (including the underscore _, the
lowercase and uppercase Latin letters, and other characters) and digits, which designates
one or more entities as described in 6.2.1 [..]
并且在 §6.2.1 中,标识符的范围
An identifier can denote an object; a function; a tag or a member of a structure, union, or
enumeration; a typedef name; a label name; a macro name; or a macro parameter.
因此,数组元素不是标识符。
不,"identifier" 严格指的是由字母数字和下划线字符构成的名称。
然而,a
、a[2]
和 a[2][4]
在这里都是 声明符。
a[2]
是一个由主表达式标识符 a
和下标运算符 [].
构建的后缀表达式
如果单独考虑声明
int a[2][4];
则此声明将标识符 a
声明为类型 int[2][4]
。
您可以使用 typedef 将标识符与声明中的其他元素分开。例如
typedef int T[2][4];
T a;
现在更清楚什么是标识符了。因此 a
是一个类型为 T
的标识符,它又等价于 int[2][4]
.
C语法中也有声明符这样的概念。例如,标识符是声明符。在下面的声明中,我将所有声明符括在括号中。
int ( ( ( a )[2] )[4] );
这是一个有效的声明,虽然看起来很混乱。:)在这个声明中 a
、a[2]
和 a[2][4]
是从标识符 [=14 开始构建的声明符=].
a[2]
不是标识符。
N15706.4.2中标识符的定义是
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined characters
nondigit: one of
_ a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
digit: one of
0 1 2 3 4 5 6 7 8 9
我认为 [
和 ]
不包含在典型 C 编译器的 "implementation-defined characters" 中,因为它们被用作数组下标运算符 (N1570 6.5.2.1)
int a[2][4] = {........};
在上面的代码中,a
是一个数组类型的标识符。但是我很好奇a[2]
,它是一个4个int元素的数组,是否也是一个标识符?
没有。标识符是例如变量或函数的名称。正如@WhozCraig 在评论中所写,它不仅是变量或函数。该术语来自语法分析器:
function ::= identifier '(' parameter ( ',' parameters )* ')'
在示例 a[2][4]
中,a
是一个标识符和一个值。 a[2]
和 a[2][4]
都是值,但不是标识符。它们也是左值,即您可以在赋值符号 =
:
a
、a[2]
和 a[2][4]
a[2][4] = 100;
不,a[2]
是数组 对象 的一个元素。引用 C11
,章节 §6.5.2.1/2,数组下标
A postfix expression followed by an expression in square brackets
[]
is a subscripted designation of an element of an array object.
从 §6.4.2.1 添加 标识符
An identifier is a sequence of nondigit characters (including the underscore _, the lowercase and uppercase Latin letters, and other characters) and digits, which designates one or more entities as described in 6.2.1 [..]
并且在 §6.2.1 中,标识符的范围
An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter.
因此,数组元素不是标识符。
不,"identifier" 严格指的是由字母数字和下划线字符构成的名称。
然而,a
、a[2]
和 a[2][4]
在这里都是 声明符。
a[2]
是一个由主表达式标识符 a
和下标运算符 [].
如果单独考虑声明
int a[2][4];
则此声明将标识符 a
声明为类型 int[2][4]
。
您可以使用 typedef 将标识符与声明中的其他元素分开。例如
typedef int T[2][4];
T a;
现在更清楚什么是标识符了。因此 a
是一个类型为 T
的标识符,它又等价于 int[2][4]
.
C语法中也有声明符这样的概念。例如,标识符是声明符。在下面的声明中,我将所有声明符括在括号中。
int ( ( ( a )[2] )[4] );
这是一个有效的声明,虽然看起来很混乱。:)在这个声明中 a
、a[2]
和 a[2][4]
是从标识符 [=14 开始构建的声明符=].
a[2]
不是标识符。
N15706.4.2中标识符的定义是
identifier: identifier-nondigit identifier identifier-nondigit identifier digit identifier-nondigit: nondigit universal-character-name other implementation-defined characters nondigit: one of _ a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z digit: one of 0 1 2 3 4 5 6 7 8 9
我认为 [
和 ]
不包含在典型 C 编译器的 "implementation-defined characters" 中,因为它们被用作数组下标运算符 (N1570 6.5.2.1)