-联系-的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 '[' ']'现在我有一些关于这些的问题:
void foo(int [*]);和
void foo(int []);谢谢。
发布于 2010-02-22 17:56:02
在C89/90中数组声明的大小部分不能使用类型限定符或static。这些特性是C99特有的。
数组声明中的static告诉编译器,您承诺指定数量的元素将始终存在于作为实际参数传递的数组中。这可能有助于编译器生成更高效的代码。如果您违背了实际代码中的承诺(即传递一个较小的数组),则该行为是未定义的。例如,
void foo(int a[static 3]) {
...
}
int main() {
int a[4], b[2];
foo(a); /* OK */
foo(b); /* Undefined behavior */
}数组声明的大小部分中的*仅用于函数原型声明。它表明数组具有可变长度(VLA)。例如,在函数定义中,可以使用具有具体运行时大小的VLA。
void foo(int n, int a[n]) /* `a` is VLA because `n` is not a constant */
{
...
}当您声明原型时,您也可以这样做。
void foo(int n, int a[n]); /* `a` is VLA because `n` is not a constant */但是,如果不指定参数名(在原型中是可以的),当然不能使用n作为数组大小。但是,如果您仍然必须告诉编译器数组将是一个VLA,则可以为此使用*。
void foo(int, int a[*]); /* `a` is VLA because size is `*` */注意,使用一维数组的示例不是一个好例子。即使您省略了*并将上面的函数声明为
void foo(int, int a[]);然后代码仍然可以正常工作,因为在函数参数声明中,数组类型被指针类型隐式替换。但是,一旦您开始使用多维数组,正确使用*就变得非常重要。例如,如果函数被定义为
void bar(int n, int m[n][n]) { /* 2D VLA */
...
}原型可能如下所示
void bar(int n, int m[n][n]); /* 2D VLA */或as
void bar(int, int m[*][*]); /* 2d VLA */在后一种情况下,可以省略第一个* (因为数组到指针的替换),但不能省略第二个*。
发布于 2010-02-22 17:52:42
我希望你不是在尝试从yacc规范中学习C语法!?您发布的链接似乎是基于国际标准化组织C99草案的。相关章节为6.7.5.2。其措辞很神秘(但可能不如yacc语法!)
发布于 2010-02-22 17:39:18
我的K&R2(涵盖并包括ANSI标准)似乎没有在文本或标准本身中提到任何关于[*]的内容。我也不能使标准中的官方语法接受这种语法。
它可能与K&R c有关(虽然我似乎不记得它),可能是一个常见的扩展,或者是一个最终没有制定标准的提案。
我假设它显式地不指定数组的维度。但我只是猜。
Hmm...gcc接受
#include <stdio.h>
void f(int s, int a[*]);
int main(void){
int a[2] = {0};
f(2,a);
return 0;
}
void f(int s, int a[]){
int i;
for (i=0; i<s; ++i){
printf("%d\n",a[i]);
}
}在ansi、c89和c99模式下;即使使用-Wall也不发出警告。注意,它不喜欢函数定义中的[*]语法。添加-pedantic使它抱怨c89和ansi模式中的[*]语法,但在c99模式下继续接受。
https://stackoverflow.com/questions/2312490
复制相似问题