微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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)(3)除外
>(4)和(5)是什么?关键字“静态”让我感到困惑
>哪里使用(6)?
>以下两个功能原型有什么区别?

void foo(int [*]);和

void foo(int []);

谢谢.

解决方法

您不能在C89 / 90中使用数组声明的类型限定符或静态大小部分.这些功能特定于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 `*` */

注意,具有1D阵列的示例不是一个好的例子.即使你省略了*并声明了上述的功能

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 */

或作为

void bar(int,int m[*][*]); /* 2d VLA */

在后一种情况下,第一个*可以省略(因为数组到指针的替换),而不是第二个*.

原文地址:https://www.jb51.cc/c/116349.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐