gpt4 book ai didi

c - C 中类型声明语句的关联

转载 作者:行者123 更新时间:2023-11-30 21:43:51 24 4
gpt4 key购买 nike

如何解析 C 中的类型声明语句(从右到左或从左到右)?

例如:考虑以下陈述:

const char* const arr="hello";

上面的语句到底是如何解析的?

亲爱的大家,对于那些觉得很难理解我的问题的人:

上面的声明语句中arr是一个变量。当编译器读取上述语句(恰好解析该行)时, arr 被视为常量变量,然后归类为字符指针,或者首先将其识别为字符指针,然后以常量值结束。怀疑是由于以下想法: 如果仅声明 const ex: const int x;然后编译器在幕后做一些事情使其成为常量,如果我只声明一个指针 ex: int* x;编译器再次在幕后将 x 分类为指针变量,以将其与另一个整数变量区分开来。但如果声明是这样的:常量 int* 常量 x;幕后操作必须以某种顺序发生,以便 x 被识别为整数指针变量和 const 变量,然后它具有常量值。 我也很高兴听到 C 编译器为区分 int 变量 char vaiable... 指针变量、寄存器变量所做的“幕后”操作,编译器如何识别差异。 最后感谢您耐心阅读这么长的问题。

最佳答案

声明不是严格从左到右或从右到左解析的。 C 声明语法有些复杂。

基于 online C2011 standard 中找到的语法,第 6.7 节,您的示例解析如下(为简洁起见,跳过几个步骤):

  char    const      *    const      arr      =    "hello"        ;
-+-- --+-- ^ --+-- -+- ^ ---+--- ^
| | | | | | | |
type type | type direct | initializer |
specifier qualifier | qualifier declarator | | |
| | | list | | | |
| | | | | | | |
| | +--+---+ | | | |
| | | | | | |
| | pointer | | | |
| | | | | | |
| | +------+------+ | | |
| | | | | |
| | declarator | | |
| | | | | |
| | +---------+----+-------+ |
| | | |
| | | |
| | | |
+---+----+ | |
| | |
declaration init-declarator-list |
specifiers | |
| | |
+-------------------------+-------+------------------------+
|
declaration

因此,关于声明的指针部分需要注意一些事情; * 后面的 const指针非终结符的一部分。这部分语法如下所示:

<em>pointer</em>:
<strong>*</strong> <em>type-qualifier-list<sub>opt</sub></em>
<strong>*</strong> <em>type-qualifier-list<sub>opt</sub></em> <em>pointer</em>

当您编写T * const p时,这意味着您将p声明为常量指针;您将无法为 p 分配不同的值(您无法使其指向不同的对象)。

这也意味着您可以声明一个对象,例如 T * const * const pT * const restrict * volatile * p;。在每种情况下,类型限定符列表都与出现在其左侧的 * 相关联。

阅读毛茸茸的声明的方法是从最左边的标识符开始,然后逐步解决,记住以下规则:

*a[]      - a is an array of pointer
(*a)[] - a is a pointer to an array
*f() - f is a function returning a pointer
(*f)() - f is a pointer to a function
* qual p - p is a qualified pointer
qual * p - p is a pointer to qualified type

其中限定可以是const volatile restrict_Atomic之一.对于函数声明,您将递归地将这些规则应用于每个函数参数。

所以,

                   arr               -- arr
* const arr -- is a const pointer to
char const * const arr -- const char
char const * const arr = "hello"; -- initialized to "hello"

也可以这样写

const char * const arr = "hello";

这意味着同样的事情。其原因是 声明说明符 非终结符(在本例中,它覆盖了 *< 左侧的声明部分)/code>) 定义为



<em>declaration-specifiers</em>:
<em>storage-class-specifier</em> <em>declaration-specifiers<sub>opt</sub></em>
<em>type-specifier</em> <em>declaration-specifiers<sub>opt</sub></em>
<em>type-qualifier</em> <em>declaration-specifiers<sub>opt</sub></em>
<em>function-specifier</em> <em>declaration-specifiers<sub>opt</sub></em>
<em>alignment-specifier</em> <em>declaration-specifiers<sub>opt</sub></em>

此语法意味着您可以拥有存储类说明符类型说明符中的任何一个>、类型限定符函数说明符对齐方式说明符后跟零个或多个附加此类项目(受某些约束)。这就是你如何获得像

这样的声明
static unsigned long int x;

解析为

static        unsigned        long        int         x        ;
--+--- ----+--- --+- -+- ^ ^
| | | | | |
storage type type type direct |
class specifier specifier specifier declarator |
specifier | | | | |
| | | declaration | |
| | | specifiers | |
| | | | | |
| | +-----+----+ | |
| | | | |
| | declaration init |
| | specifiers declarator |
| | | | |
| +---------+---------+ | |
| | | |
| declaration | |
| specifiers | |
| | | |
+-----------+-------------+ init |
| declarator |
declaration-specifiers list |
| | |
+----------------------+----------------+--------+
|
declaration

staticunsignedlongint 出现的顺序并不重要(尽管如果你写 int long static unsigned x ,人们可能会打你)。您的声明必须至少包含一个类型说明符,并且不能编写诸如 float char double xdouble double 之类的内容double double y,但这些规则是在不同级别执行的。

关于c - C 中类型声明语句的关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29629600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com