ANSI-C 语法 - 数组声明,如 [*] 等
-link- 中的 ANSI C 语法给了我以下规则对于数组声明:
(1) | direct_declarator '[' type_qualifier_list assignment_expression ']'
(2) | direct_declarator '[' type_qualifier_list ']'
(3) | direct_declarator '[' assignment_expression ']'
(4) | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
(5) | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
(6) | direct_declarator '[' type_qualifier_list '*' ']'
(7) | direct_declarator '[' '*' ']'
(8) | direct_declarator '[' ']'
现在我有一些关于这些的问题:
- 我可以仅在 C99 中使用 (1) - (6) except (3) 吗?
- (4)和(5)有什么用?关键字“静态”让我感到困惑。
- 在哪里使用(6)?
以下两个函数原型有什么区别:
void foo(int [*]);
和void foo(int []);
谢谢。
The ANSI C grammar from -link- give me the following rules for array declarations:
(1) | direct_declarator '[' type_qualifier_list assignment_expression ']'
(2) | direct_declarator '[' type_qualifier_list ']'
(3) | direct_declarator '[' assignment_expression ']'
(4) | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
(5) | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
(6) | direct_declarator '[' type_qualifier_list '*' ']'
(7) | direct_declarator '[' '*' ']'
(8) | direct_declarator '[' ']'
Now I have a some questions about these:
- Can I use (1) - (6) except (3) only in C99?
- What are (4) and (5) for? The keyword 'static' confuses me.
- Where to use (6)?
What's the difference between the following two function prototypes:
void foo(int [*]);
andvoid foo(int []);
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 C89/90 中,不能在数组声明的大小部分中使用类型限定符或
static
。这些功能是 C99 特有的。数组声明中的
static
告诉编译器您承诺指定数量的元素将始终出现在作为实际参数传递的数组中。这可能有助于编译器生成更高效的代码。如果您在实际代码中违反了承诺(即传递较小的数组),则行为是未定义的。例如,数组声明的 size 部分中的
*
仅在函数原型声明中使用。它表明该数组具有可变长度(VLA)。例如,在函数定义中,您可以使用具有具体运行时大小的 VLA当您声明原型时,您可以执行相同的操作
,但如果您不指定参数名称(这在原型中是可以的),您可以当然,不要使用
n
作为数组大小。然而,如果您仍然需要告诉编译器该数组将是一个 VLA,您可以使用*
来实现此目的。请注意,带有一维数组的示例不是一个好的示例。即使您省略
*
并声明上述函数,代码仍然可以正常工作,因为在函数参数声明中,数组类型无论如何都会隐式替换为指针类型。但是一旦开始使用多维数组,正确使用
*
就变得很重要。例如,如果函数被定义为原型可能如下所示
或
在后一种情况下,可以省略第一个
*
(因为数组到指针的替换),但不能省略第二个*
。You can't use type qualifiers or
static
in size portion of array declaration in C89/90. These features are specific to C99.static
in array declaration tells the compiler that you promise that the specified number of elements will always be present in the array passed as the actual argument. This might help compilers to generate more efficient code. If you violate your promise in the actual code (i.e. pass a smaller array), the behavior is undefined. For example,The
*
in size portion of array declaration is used in function prototype declarations only. It indicates that the array has variable length (VLA). For example, in the function definition you can use a VLA with a concrete run-time sizeWhen you declare the prototype you can do the same
but if you don't specify the parameter names (which is OK in the prototype), you can't use
n
as array size of course. Yet, if you still have to tell the compiler that the array is going to be a VLA, you can use the*
for that purposeNote, that the example with a 1D array is not a good one. Even if you omit the
*
and declare the above function asthen the code will still work fine, because in function parameter declarations array type is implicitly replaced with pointer type anyway. But once you start using multi-dimensional arrays, the proper use of
*
becomes important. For example, if the function is defined asthe the prototype might look as follows
or as
In the latter case the first
*
can be omitted (because of the array-to-pointer replacement), but not the second*
.我希望您不是试图从 yacc 规范中学习 C 语法!?您发布的链接似乎基于 ISO C99草稿。相关章节为 6.7.5.2。措辞很晦涩(但也许不如 yacc 语法那么晦涩!)
I hope you are not trying to learn C grammar from a yacc specification!? The link you posted appears to be based on the ISO C99 draft. The relevant section is 6.7.5.2. The wording is arcane (but less so than the yacc syntax perhaps!)
我的 K&R2nd(涵盖并包括 ANSI 标准)似乎没有在文本中或标准本身中提及任何有关
[*]
的内容。我也无法使标准中的官方语法接受该语法。它可能与 K&R c 有关(虽然我似乎不记得了),可能是一个常见的扩展,或者是一个最终没有成为标准的提案。
我假设它使数组的维度明确未指定。但我只是猜测。
嗯...gcc 接受
ansi、c89 和 c99 模式;即使使用
-Wall
也不会发出警告。请注意,它不喜欢函数定义中的[*]
语法。添加-pedantic
使其抱怨 c89 和 ansi 模式中的[*]
语法,但它继续在 c99 模式中接受。My K&R2nd (which covers and includes the ANSI standard) does not seem to say anything about
[*]
either in the text, or in the standard itself. Nor can I make the official grammar in the standard accept that syntax.It may be related to K&R c (though I don't seem to recall it), may have been a common extension, or have been a proposal that ultimately didn't make the standard.
I would assume it makes the dimension of the array explicitly unspecified. But I'm just guessing.
Hmm...gcc accepts
in ansi, c89 and c99 mode; issuing no warnings even with
-Wall
. Note that it did not like the[*]
syntax in the function definition. Adding-pedantic
made it complain about the[*]
syntax in c89 and ansi modes, but it continued to accept in in c99 mode.