C ++中的声明 [英] Declarations in C++

查看:183
本文介绍了C ++中的声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,C ++中的声明/初始化是带有基本类型"的语句,后跟逗号分隔的声明符列表.

From what I have understood, declarations/initializations in C++ are statements with 'base type' followed by a comma separated list of declarators.

请考虑以下声明:

int i = 0, *const p = &i; // Legal, the so-called base type is 'int'.
                          // i is an int while p is a const pointer to an int.

int j = 0, const c = 2;   // Error: C++ requires a type specifier for all declarations.
                          // Intention was to declare j as an int and c an as const int.

int *const p1 = nullptr, i1 = 0; // p1 is a const pointer to an int while i1 is just an int.

int const j1 = 0, c1 = 2;   // Both j1 and c1 are const int.

const int是基本类型还是复合类型?

Is const int a base type or a compound type?

从上面第二个声明中的错误来看,它似乎是基本类型.如果是这样,那么第一个声明呢?

From the error in the second declaration above, it seems to be a base type. If it is so, then what about the first declaration?

换句话说,如果第一个陈述是合法的,为什么第二个陈述不合法?另外,为什么第三和第四条语句的行为有所不同?

In other words, if the first statement is legal, why isn't the second one? Also, why does the behaviour differ among the third and fourth statements?

推荐答案

好问题,答案很复杂.要真正掌握这一点,您需要非常全面地了解C ++声明的内部结构.

Good question, with a complicated answer. To really grasp this, you need to understand the internal structure of C++ declarations quite thoroughly.

(请注意,在此答案中,我将完全省略属性的存在以防止过度复杂化).

(Note that in this answer, I will totally omit the existence of attributes to prevent overcomplication).

声明有两个组成部分:一系列声明符,后跟一个用逗号分隔的 init-declarators 列表.

A declaration has two components: a sequence of specifiers, followed by a comma-separated list of init-declarators.

说明符如下:

  • 存储类说明符(例如staticextern)
  • 功能说明符(例如virtualinline)
  • friendtypedefconstexpr
  • 类型说明符,其中包括:
    • 简单类型说明符(例如intshort)
    • cv限定词(constvolatile)
    • 其他事物(例如decltype)
    • storage class specifiers (e.g. static, extern)
    • function specifiers (e.g. virtual, inline)
    • friend, typedef, constexpr
    • type specifiers, which include:
      • simple type specifiers (e.g. int, short)
      • cv-qualifiers (const, volatile)
      • other things (e.g. decltype)

      声明的第二部分是逗号分隔的init声明符.每个init-declarator由一系列声明符组成,可选地,后面还有一个 initializer.

      The second part of a declaration are the comma-separated init-declarators. Each init-declarator consists of a sequence of declarators, optionally followed by an initialiser.

      什么是声明符?

      • 标识符(例如int i;中的i)
      • 类似指针的运算符(*&&&,指针到成员的语法)
      • 函数参数语法(例如(int, char))
      • 数组语法(例如[2][3])
      • cv限定符(如果它们遵循指针声明符).
      • identifier (e.g. the i in int i;)
      • pointer-like operators (*, &, &&, pointer-to-member syntax)
      • function parameter syntax (e.g. (int, char))
      • array syntax (e.g. [2][3])
      • cv-qualifiers, if these follow a pointer declarator.

      请注意,声明的结构很严格:首先是声明符,然后是init声明符(每个声明符都可以有选择地后面是初始化符).

      Notice that the declaration's structure is strict: first specifiers, then init-declarators (each being declarators optionally followed by an initialiser).

      规则是:说明符适用于整个声明,而声明符仅适用于一个init-declarator(逗号分隔列表的一个元素).

      The rule is: specifiers apply to the entire declaration, while declarators apply only to the one init-declarator (to the one element of the comma-separated list).

      上面还请注意,cv限定符既可以用作说明符,也可以用作声明符.作为声明符,语法将其限制为只能在存在指针的情况下使用.

      Also notice above that a cv-qualifier can be used as both a specifier and a declarator. As a declarator, the grammar restricts them to only be used in the presence of pointers.

      因此,要处理您发布的四个声明:

      So, to handle the four declarations you have posted:

      int i = 0, *const p = &i;
      

      说明符部分仅包含一个说明符:int.这就是所有声明符都将要应用的部分.

      The specifier part contains just one specifier: int. That is the part that all declarators will apply to.

      有两个init声明符:i = 0* const p = &i.

      There are two init-declarators: i = 0 and * const p = &i.

      第一个有一个声明符i和一个初始化程序= 0.由于没有类型修改声明符,因此i的类型由说明符给定,在这种情况下为int.

      The first one has one declarator, i, and an initialiser = 0. Since there is no type-modifying declarator, the type of i is given by the specifiers, int in this case.

      第二个init声明符具有三个声明符:*constp.还有一个初始化程序= &i.

      The second init-declarator has three declarators: *, const, and p. And an initialiser, = &i.

      声明符*const修改基类型以表示指向基类型的常量指针".说明符给出的基本类型是intp的类型将是指向int的恒定指针".

      The declarators * and const modify the base type to mean "constant pointer to the base type." The base type, given by specifiers, is int, to the type of p will be "constant pointer to int."

      int j = 0, const c = 2;
      

      同样,一个说明符:int,以及两个初始化声明符:j = 0const c = 2.

      Again, one specifier: int, and two init-declarators: j = 0 and const c = 2.

      对于第二个init声明符,声明符为constc.正如我提到的那样,如果涉及到指针,则语法仅允许cv限定词作为声明符.这里不是这种情况,因此是错误.

      For the second init-declarator, the declarators are const and c. As I mentioned, the grammar only allows cv-qualifiers as declarators if there is a pointer involved. That is not the case here, hence the error.

      int *const p1 = nullptr, i1 = 0;
      

      一个说明符:int,两个初始化声明符:* const p1 = nullptri1 = 0.

      One specifier: int, two init-declarators: * const p1 = nullptr and i1 = 0.

      对于第一个init声明符,声明符为:*constp1.我们已经处理过这样的init声明符(在 1 情况下是第二个).它将指向基本类型的常量指针"添加到说明符定义的基本类型(仍为int).

      For the first init-declarator, the declarators are: *, const, and p1. We already dealt with such an init-declarator (the second one in case 1). It adds the "constant pointer to base type" to the specifier-defined base type (which is still int).

      对于第二个init声明器i1 = 0来说,这是显而易见的.没有类型修改,请按原样使用说明符.因此i1变为int.

      For the second init-declarator i1 = 0, it's obvious. No type modifications, use the specifier(s) as-is. So i1 becomes an int.

      int const j1 = 0, c1 = 2;
      

      在这里,我们与前三个情况截然不同.我们有两个说明符:intconst.然后是两个init声明符,分别是j1 = 0c1 = 2.

      Here, we have a fundamentally different situation from the preceding three. We have two specifiers: int and const. And then two init-declarators, j1 = 0 and c1 = 2.

      这些init声明符中都没有任何可进行类型修改的声明符,因此它们都使用说明符中的类型,即const int.

      None of these init-declarators have any type-modifying declarators in them, so they both use the type from the specifiers, which is const int.

      这篇关于C ++中的声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆