侧边栏壁纸
  • 累计撰写 47 篇文章
  • 累计创建 0 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

C++ 指针和常量混合定义时的解读

理解的时候从左往右一层一层解读

I const int * const * const x; 什么意思?

在C++中,声明 const int * const * const x; 可能会因为多重使用 const 而显得非常混乱。我们可以逐步分解来理解:

  1. const int - 这指定了指向的整数是常量,不能被修改。

  2. const int * - 这是一个指向常量整数的指针。通过这个指针,不能修改其指向的整数值。

  3. const int * const - 这是一个指向常量整数的常量指针。这个指针本身不能被更改指向另一个整数,而且它所指向的整数值也不能被修改。

  4. const int * const * - 这是一个指向常量指针(指向常量整数)的指针。这个指针可以指向不同的常量指针(这些常量指针不能改变它们的目标整数,目标整数也不能被修改)。

  5. const int * const * const x - 这是一个指向指向常量指针(指向常量整数)的常量指针。换句话说,x 是一个常量指针,所以 x 本身不能被改变为指向其他位置。*x 也是一个常量指针,意味着 x 所指向的指针不能改变。最后,这个二级指针所指向的整数值也是常量,不能被修改。

让我们一步步分解:

  • 第一个 const(最接近 x)表示 x 本身是一个常量指针。你不能改变 x 指向其他东西。
  • 第二个 const(在 * const * const x 之前)表示 *x 是一个常量指针。你不能改变 x 指向的指针的值。
  • 第三个 const(在 int * 之前)表示 **x 指向的是一个常量整数。你不能修改 **x 所指向的整数值。

这里有一个图示帮助理解:

x -> const int * const -> const int

总之,x 是一个指向常量指针(指向常量整数)的常量指针。x 和它所指向的指针都不能被改变,最终指向的整数值也是不可变的。

II const int **x; 什么意思?是否和 const int * const * const x; 等价?

const int **x;const int * const * const x; 是两种不同的声明,它们并不等价。我们逐一分析这两种声明的含义:

const int **x

  1. int - 表示一个整数。
  2. const int - 表示一个常量整数。
  3. const int * - 表示一个指向常量整数的指针。
  4. const int ** - 表示一个指向指向常量整数的指针的指针。

也就是说,x 是一个指针,指向一个指针,该指针指向一个常量整数。在这种情况下:

  • 你可以改变 x 指向的指针(即 x 可以指向不同的指针)。
  • 你可以改变 *x 指向的指针(即 *x 可以指向不同的 const int 指针)。
  • 你不能改变 **x 所指向的整数值,因为它是一个常量整数。

const int * const * const x

  1. const int - 表示一个常量整数。
  2. const int * - 表示一个指向常量整数的指针。
  3. const int * const - 表示一个常量指针,指向常量整数。
  4. const int * const * - 表示一个指向常量指针(指向常量整数)的指针。
  5. const int * const * const - 表示一个常量指针,指向一个常量指针(指向常量整数)。

在这种情况下:

  • x 是一个常量指针,不能改变它指向的地址。
  • *x 也是一个常量指针,不能改变它指向的地址。
  • **x 是一个常量整数,不能改变它的值。

总结

  • const int **x 表示 x 是一个指向指向常量整数的指针的指针。你可以改变 x*x 的指向,但不能改变 **x 指向的整数值。
  • const int * const * const x 表示 x 是一个常量指针,指向一个常量指针,该常量指针指向一个常量整数。你不能改变 x*x**x 的指向或值。

这两者在语义和用途上完全不同,因此不等价。

III const int** x;const int **x; 有区别吗?

const int** x;const int **x; 在C++中是等价的。它们都表示一个指向指向常量整数的指针的指针。

解释

  • const int - 表示一个常量整数。
  • const int * - 表示一个指向常量整数的指针。
  • const int ** - 表示一个指向指向常量整数的指针的指针。

无论空格如何,const int** x;const int **x; 都意味着 x 是一个指向指针的指针,该指针指向一个 const int 类型的常量整数。因此,空格在这种情况下不会影响声明的含义。

为了更清楚地理解,下面是一些示例:

示例代码

const int a = 10;      // a 是一个常量整数
const int *p = &a;     // p 是一个指向常量整数的指针
const int **x = &p;    // x 是一个指向指向常量整数的指针的指针

上述代码中的 const int** xconst int **x 在功能和用途上没有任何区别。

结论

在C++中,空格在声明中的位置对于类型定义没有影响。const int** x;const int **x; 是完全等价的声明,表示 x 是一个指向指向常量整数的指针的指针。

IV 更推荐哪种写法?

在C++中,推荐的写法主要取决于代码的可读性和一致性。虽然 const int** x;const int **x; 在语义上是等价的,通常建议遵循一些通用的编码风格指南来提高代码的可读性。

推荐的写法

  1. 使用一致的空格:通常建议在指针声明中保持空格的一致性。这可以提高代码的可读性,让其他开发者更容易理解代码。
  2. 靠近类型修饰符:将 const 放在它修饰的类型旁边,可以更清晰地表示它修饰的对象。

例如:

const int** x;  // 推荐

具体建议

  1. const 放在靠近它修饰的类型旁边:这使得代码更易于理解。例如,const int* 清楚地表示这是一个指向 const int 的指针。

  2. 在星号前后保持一致的空格:这通常是团队一致约定的编码风格。例如:

    • const int* const* const x;(如果团队习惯不在星号前后加空格)
    • const int * const * const x;(如果团队习惯在星号前后加空格)

示例

推荐的写法是:

const int **x;  // 推荐的写法,清晰地表示 x 是一个指向指向常量整数的指针的指针

代码风格一致性

无论选择哪种方式,最重要的是在整个代码库中保持一致的风格。这有助于提高代码的可维护性和可读性。通常,团队会有自己的编码规范,可以参考这些规范来决定具体的书写风格。

总结来说,在指针声明中保持空格的一致性并将 const 放在靠近它修饰的类型旁边是推荐的做法。具体选择哪种风格可以根据团队的编码规范来决定。

V int const **x;int** const x; 等价吗?更推荐哪种写法?

int const **x;int** const x; 在C++中是不等价的。这两种声明表达了不同的含义。

int const **x;

  1. int constconst int 是一个常量整数,表示整数值不能被修改。
  2. int const *const int * 是一个指向常量整数的指针。
  3. int const **xconst int **x 是一个指向指向常量整数的指针的指针。

这意味着 x 是一个指针,指向一个指向 const int 的指针。你可以改变 x 指向的指针以及该指针指向的指针,但不能改变 **x 所指向的整数值。

int** const x;

  1. int** 是一个指向指针的指针,指向一个普通的整数。
  2. int** const x 表示 x 是一个常量指针,指向一个指向整数的指针。

这意味着 x 是一个常量指针,指向一个指向 int 的指针。你不能改变 x 本身指向的地址,但你可以改变 *x**x 所指向的整数值。

具体区别

  • int const **x; 表示 x 是一个可以改变的指针,指向一个可以改变的指针,但最终指向的整数值不能改变。
  • int** const x; 表示 x 是一个常量指针,不能改变其指向,但可以改变它所指向的指针以及指针指向的整数值。

示例代码

#include <iostream>

using namespace std;

int main() {
    // int const **x example
    int const a = 10;
    int const b = 20;
    int const *p1 = &a;
    int const *p2 = &b;
    int const **x = &p1;
    cout << &a << " " << p1 << " " << &p1 << " " << x << " " << *x << endl;    
    cout << p2 << " " << &p2 << endl;
    x = &p2;  // OK: you can change the pointer x points to
    // **x = 30;  // Error: you cannot change the value of const int
    cout << &b << " " << p2 << " " << &p2 << " " << x << " " << *x << endl;
    
    // int** const x example
    int c = 30;
    int d = 40;
    int *p3 = &c;
    int *p4 = &d;
    int** const y = &p3;
    // y = &p4;  // Error: you cannot change the value of the const pointer y
    *y = p4;   // OK: you can change the pointer y points to
    **y = 50;  // OK: you can change the value of the pointed integer

    return 0;
}

更推荐哪种写法

哪个写法更好取决于你的需求:

  • 如果你需要一个可以改变的指针,指向一个指向常量整数的指针,使用 int const **x;
  • 如果你需要一个常量指针,指向一个可以改变的指向整数的指针,使用 int** const x;

在实际使用中,建议选择适合语义的声明,并在团队中保持一致的编码风格。一般来说,尽量使代码的意图清晰易懂是最重要的。

0

评论区