You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于C17标准中赋值表达式及数组声明语法的疑问

关于C17标准中赋值表达式及数组声明语法的疑问

嘿,作为C新手啃标准文档里的语法定义,头大简直太正常了!我来帮你把这段C17标准6.7.6.2/3的数组声明规则拆解得明明白白~

先把你看到的标准原文放出来方便对照:

If, in the declaration “T D1”, D1 has one of the forms:
D [ type-qualifier-listopt assignment-expressionopt ]
D [ type-qualifier-listopt assignment-expression ]
D [ type-qualifier-list static assignment-expression ]
D [ type-qualifier-listopt ]
and the type specified for ident in the declaration “T D” is “derived-declarator-type-list T”, then the type specified for ident is...

首先得先搞懂几个关键术语的意思,不然看语法像看天书:

  • T 就是咱们平时写的基本类型,比如int、char、float这些;
  • opt 是optional的缩写,意思是后面跟着的内容是可选的,可写可不写;
  • type-qualifier-list 指的是const、volatile这类用来限定类型的关键字;
  • assignment-expression 就是用来指定数组大小的表达式,像字面常量10、sizeof(long)这种都算。

接下来咱们逐个拆解这四种数组声明形式:

  • 第一种形式:D [ type-qualifier-listopt assignment-expressionopt ]
    这是最灵活的写法,限定符和大小表达式都可以省略。比如全局作用域的int arr[];(没指定大小,属于“不完全类型”,后面定义的时候得补全大小),或者const int arr[10];(带const限定符和固定大小),甚至函数里的可变长数组int n = 8; int arr[n];(用变量作为大小表达式)都属于这种情况。
  • 第二种形式:D [ type-qualifier-listopt assignment-expression ]
    这种和第一种的核心区别是必须指定大小表达式,不能空着。比如volatile char arr[20];(带volatile限定符和固定大小),或者函数里的int arr[sizeof(int)*5];(用编译期表达式指定大小),都是这种写法。
  • 第三种形式:D [ type-qualifier-list static assignment-expression ]
    这里多了个static关键字,注意哦——这种写法只能用在函数的参数声明里!它的意思是要求传入的数组至少有指定的元素个数,编译器可以基于这个信息做一些优化。比如void calc(int nums[static 6]),就表示nums指向的数组至少有6个int元素。
  • 第四种形式:D [ type-qualifier-listopt ]
    这就是完全省略大小的数组声明,最常见的场景有两个:一个是全局作用域的不完全类型数组(比如int arr[];,后面需要用int arr[5] = {1,2,3,4,5};来补全定义);另一个是函数参数列表里,int arr[]其实等价于int *arr,不过写法上用数组形式更直观表达参数的用途。

最后补充下标准里没写完的后半句:当满足前面的声明形式时,标识符的类型会变成“derived-declarator-type-list array of assignment-expression T”(或者对应变体),也就是在原来的类型基础上,把它变成数组类型。

备注:内容来源于stack exchange,提问作者ALICEZzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:23:07