【问题标题】:What is the difference between const int*, const int * const, and int const *?const int*、const int * const 和 int const * 有什么区别?
【发布时间】:2010-11-11 17:04:04
【问题描述】:

我总是搞砸如何正确使用const int*const int * constint const *。是否有一套规则来定义你能做什么和不能做什么?

我想知道在分配、传递给函数等方面的所有注意事项。

【问题讨论】:

  • 您可以使用"Clockwise/Spiral Rule" 来破译大多数 C 和 C++ 声明。
  • cdecl.org 是一个很棒的网站,可以为您自动翻译 C 声明。
  • @Calmarius:从类型名称 / 应该在的位置开始,尽可能向右移动,必须向左移动int *(*)(char const * const)。从带括号的* 的右侧开始,然后我们必须向左移动:pointer。在括号外,我们可以向右移动:pointer to function of ...。然后我们必须向左移动:pointer to function of ... that returns pointer to int。重复展开参数(...):pointer to function of (constant pointer to constant char) that returns pointer to int。在像 Pascal 这样易于阅读的语言中,等效的单行声明会是什么?
  • @MarkKCowan 在 Pascal 中类似于function(x:^char):^int。函数类型意味着指向函数的指针,因此无需指定它,并且 Pascal 不强制 const 正确性。可以从左到右阅读。
  • “const”左边的第一件事是常数。如果“const”是最左边的东西,那么它右边的第一个东西就是常数。

标签: c++ c pointers constants c++-faq


【解决方案1】:

向后阅读(由Clockwise/Spiral Rule驱动):

  • int* - 指向 int 的指针
  • int const * - 指向 const int 的指针
  • int * const - 指向 int 的 const 指针
  • int const * const - 指向 const int 的 const 指针

现在第一个 const 可以在类型的任一侧,所以:

  • const int * == int const *
  • const int * const == int const * const

如果你真的想发疯,你可以这样做:

  • int ** - 指向 int 的指针
  • int ** const - 一个指向 int 指针的 const 指针
  • int * const * - 指向 int 的 const 指针
  • int const ** - 指向 const int 的指针
  • int * const * const - 一个指向 int 的 const 指针的 const 指针
  • ...

为了确保我们清楚const 的含义:

int a = 5, b = 10, c = 15;

const int* foo;     // pointer to constant int.
foo = &a;           // assignment to where foo points to.

/* dummy statement*/
*foo = 6;           // the value of a can´t get changed through the pointer.

foo = &b;           // the pointer foo can be changed.



int *const bar = &c;  // constant pointer to int 
                      // note, you actually need to set the pointer 
                      // here because you can't change it later ;)

*bar = 16;            // the value of c can be changed through the pointer.    

/* dummy statement*/
bar = &a;             // not possible because bar is a constant pointer.           

foo 是一个指向常量整数的变量指针。这使您可以更改指向的内容,但不能更改指向的值。最常见的情况是 C 风格的字符串,其中有一个指向 const char 的指针。您可以更改指向的字符串,但不能更改这些字符串的内容。当字符串本身位于程序的数据段中并且不应更改时,这一点很重要。

bar 是一个常量或固定指针,指向可以更改的值。这就像一个没有额外语法糖的参考。由于这个事实,通常你会使用一个引用来使用 T* const 指针,除非你需要允许 NULL 指针。

【讨论】:

  • 我想附加一条经验法则,它可以帮助您记住如何发现 'const' 是否适用于指针或指向的数据:将语句拆分为星号,然后,如果 const 关键字出现在左侧(如在'const int * foo'中) - 它属于指向数据,如果它在右侧('int * const bar') - 它与指针有关。
  • @Michael:感谢 Michael 为记住/理解 const 规则提供了如此简单的规则。
  • @Jeffrey:只要没有括号,就可以向后阅读。那么,嗯……use typedefs
  • +1,虽然更好的总结是:向后读取指针声明,这意味着接近@Michael 的声明:停止正常的从左到右读取在第一个星号。
  • @gedamial 确实如此,它工作正常,但您必须在声明它的同时分配它(因为您不能重新分配“const 指针”)。 const int x = 0; const int *const px = &x; const int *const *const p = &px; 工作得很好。
【解决方案2】:

对于那些不了解顺时针/螺旋规则的人: 从变量名开始,顺时针移动(在本例中,向后移动)到下一个pointertype。重复直到表达式结束。

这是一个演示:

【讨论】:

  • @Jan 复杂示例的链接没有权限。可以直接发到这里,还是去掉查看限制?
  • @Rog 它曾经拥有所有开放访问权限...不幸的是,我没有写这篇文章并且自己没有访问权限。但是,这里有一个仍然有效的文章存档版本:archive.is/SsfMX
  • 这个复杂的例子仍然是从右到左的,但包括以通常的方式解析括号。整个顺时针螺旋的事情并没有让这变得更容易。
  • 终极示例:来自archive.is/SsfMX的void (*signal(int, void (*fp)(int)))(int);
  • 不要依赖这个规则。这不是普遍的。在某些情况下它会失败。
【解决方案3】:

我认为这里已经回答了所有问题,但我只想补充一点,您应该提防typedefs!它们不仅仅是文本替换。

例如:

typedef char *ASTRING;
const ASTRING astring;

astring 的类型是 char * const,而不是 const char *。这也是我总是倾向于将const 放在类型右侧而不是开头的原因之一。

【讨论】:

  • 对我来说,这就是从不使用 typedef 指针的原因。我没有看到像 typedef int* PINT 这样的好处(我认为它来自 C 中的实践,许多开发人员一直在这样做)。太好了,我用P 替换了*,它不会加快打字速度,而且还引入了您提到的问题。
  • @Mephane - 我可以看到。然而,对我来说,为了继续使用特殊的语法规则(关于“const”放置),避免使用一个好的语言特性似乎有点倒退,而不是避免使用特殊的语法规则,这样你就可以安全地使用这个语言特性.
  • @Mephane PINT 确实是一个相当愚蠢的 typedef 用法,尤其是因为它让我认为系统存储使用啤酒作为内存。不过 typedef 对于处理指向函数的指针非常有用。
  • @KazDragon 谢谢!如果没有它,我会在 Win32 api 中搞乱所有那些 typedefed PVOIDLPTSTR 的东西!
  • @Mephane:在使用某些为接受类型而编写的旧版宏时,我不得不使用 pSomething 几次,但如果该类型不是单个字母数字标识符,则会分解。 :)
【解决方案4】:

就像几乎每个人都指出的那样:

What’s the difference between const X* p, X* const p and const X* const p?

你必须阅读指针声明 从右到左。

  • const X* p 表示“p 指向一个 const 的 X”:X 对象不能通过 p 更改。

  • X* const p 表示“p 是指向非 const 的 X 的 const 指针”:不能更改指针 p 本身,但可以通过 p 更改 X 对象。

  • const X* const p的意思是“p是一个const指针,指向一个为const的X”:不能改变指针p本身,也不能通过p改变X对象。

    李>

【讨论】:

  • 别忘了const X* p; == X const * p; 就像"p points to an X that is const": the X object can't be changed via p.一样
【解决方案5】:
  1. 常量引用:

    对变量(此处为 int)的引用,该变量是常量。我们主要将变量作为引用传递,因为引用的大小比实际值小,但有一个副作用,那就是因为它就像实际变量的别名。我们可能会通过对别名的完全访问而意外更改主变量,因此我们将其设为常量以防止这种副作用。

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
    
  2. 常量指针

    一旦常量指针指向一个变量,它就不能指向任何其他变量。

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
    
  3. 指向常量的指针

    不能改变它所指向的变量值的指针称为常量指针。

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
    
  4. 指向常量的常量指针

    指向常量的常量指针是一个既不能改变它所指向的地址也不能改变保存在该地址的值的指针。

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error
    

【讨论】:

    【解决方案6】:

    一般规则是const 关键字适用于紧接在它之前的内容。例外情况,起始 const 适用于以下内容。

    • const int*int const* 相同,表示“指向常量 int 的指针”
    • const int* constint const* const 相同,表示“指向常量 int 的常量指针”

    编辑: 对于注意事项,如果this answer 还不够,您能否更准确地说明您想要什么?

    【讨论】:

      【解决方案7】:

      这个问题准确地显示了为什么我喜欢按照我在问题is const after type id acceptable?中提到的方式做事

      简而言之,我发现记住规则的最简单方法是“const”它适用的事物之后。所以在你的问题中,“int const *”表示int是常量,而“int * const”表示指针是常量。

      如果有人决定把它放在最前面(例如:“const int *”),作为一种特殊例外,它适用于它后面的东西。

      很多人喜欢使用这个特殊的例外,因为他们认为它看起来更好。我不喜欢它,因为它是一个例外,从而使事情变得混乱。

      【讨论】:

      • 我在这个问题上很纠结。从逻辑上讲,这是有道理的。然而,大多数 c++ 开发人员会写 const T* 并且它变得更加自然。无论如何,您多久使用一次T* const,通常参考就可以了。当我想要boost::shared_ptr<const T> 时,我被这一切所困扰,而是写了const boost::shared_ptr<T>。在略有不同的上下文中出现相同的问题。
      • 实际上,我使用常量指针的次数比使用常量的次数要多。此外,您必须考虑在存在指向指针的指针(等)的情况下您将如何反应。诚然,这些情况很少见,但是以一种可以轻松处理这些情况的方式来思考事情会很好。
      • 将 const 放在类型右侧的另一个好处是,现在任何 const 左侧的所有内容都是 const 的类型,而其右侧的所有内容都是实际上是 const 的。以int const * const * p; 为例。不,我通常不会那样写,这只是一个例子。首先const:类型int,而int即const是const指针的内容,即p的内容。第二个const:type是指向constint的指针,const oblect是p的内容
      【解决方案8】:

      const 的简单使用。

      最简单的用法是声明一个命名常量。为此,需要将常量声明为变量,但在其前面添加const。必须立即在构造函数中对其进行初始化,因为当然,以后不能设置值,因为那样会改变它。例如:

      const int Constant1=96; 
      

      将创建一个整数常量,名称为 Constant1,其值为 96。

      此类常量对于程序中使用但在程序编译后不需要更改的参数很有用。对于程序员来说,它比 C 预处理器 #define 命令具有优势,因为它可以被编译器本身理解和使用,而不仅仅是在到达主编译器之前由预处理器替换到程序文本中,因此错误消息更有帮助。

      它也适用于指针,但必须小心const 的位置,以确定指针或其指向的内容是常量还是两者兼而有之。例如:

      const int * Constant2 
      

      声明Constant2 是指向一个常量整数的变量指针,并且:

      int const * Constant2
      

      是一种替代语法,其作用相同,而

      int * const Constant3
      

      声明Constant3 是指向变量整数的常量指针,并且

      int const * const Constant4
      

      声明Constant4 是指向一个常量整数的常量指针。基本上,“const”适用于其最左边的任何东西(除非那里没有任何东西,在这种情况下它适用于它最右边的任何东西)。

      参考:http://duramecho.com/ComputerInformation/WhyHowCppConst.html

      【讨论】:

        【解决方案9】:

        在我遇到 C++ 大师 Scott Meyers 的 book 之前,我和你有同样的疑问。请参阅本书的第三条,他详细介绍了使用const

        请遵循此建议

        1. 如果单词const 出现在星号的左侧,则所指向的内容是不变的
        2. 如果单词const出现在星号的右侧,则指针本身是常量
        3. 如果const出现在两边,都是常数

        【讨论】:

          【解决方案10】:

          这很简单但很棘手。请注意,我们可以将const 限定符应用于任何数据类型(intcharfloat 等)。

          让我们看看下面的例子。


          const int *p ==> *p 是只读的 [p 是一个指向常量整数的指针]

          int const *p ==> *p 是只读的 [p 是一个指向常量整数的指针]


          int *p const ==> 错误声明。编译器抛出语法错误。

          int *const p ==> p 是只读的 [p 是一个指向整数的常量指针]。 因为这里的指针p是只读的,所以声明和定义应该在同一个地方。


          const int *p const ==> 错误声明。编译器抛出语法错误。

          const int const *p ==> *p 是只读的

          const int *const p ==> *pp 是只读的 [p 是指向常量整数的常量指针]。由于这里的指针p是只读的,所以声明和定义应该在同一个地方。


          int const *p const ==> 错误声明。编译器抛出语法错误。

          int const int *p ==> 错误声明。编译器抛出语法错误。

          int const const *p ==> *p 是只读的,相当于int const *p

          int const *const p ==> *pp 是只读的 [p 是指向常量整数的常量指针]。由于这里的指针p是只读的,所以声明和定义应该在同一个地方。

          【讨论】:

            【解决方案11】:

            对我来说,const 的位置,即它相对于* 出现在左侧还是右侧,或者同时出现在左侧和右侧,这有助于我弄清楚实际含义。

            1. *左侧的const表示指针指向的对象是const对象。

            2. * 右侧的const 表示指针是const 指针。

            下表摘自斯坦福 CS106L 标准 C++ 编程实验室课程阅读器。

            【讨论】:

            • 指针的“重新分配”和“修改”有什么区别?
            【解决方案12】:

            围绕 C++ 中的 const 正确性还有许多其他细微之处。我想这里的问题只是关于 C,但我会给出一些相关的例子,因为标签是 C++:

            • 您经常将大参数(如字符串)作为TYPE const & 传递,这会阻止对象被修改或复制。示例:

              TYPE& TYPE::operator=(const TYPE &rhs) { ... return *this; }

              但是TYPE & const 是没有意义的,因为引用总是常量。

            • 您应该始终将不修改类的类方法标记为const,否则您无法从TYPE const & 引用中调用该方法。示例:

              bool TYPE::operator==(const TYPE &rhs) const { ... }

            • 在一些常见的情况下,返回值和方法都应该是 const。示例:

              const TYPE TYPE::operator+(const TYPE &rhs) const { ... }

              事实上,const 方法不能返回内部类数据作为对非 const 的引用。

            • 因此,必须经常使用 const 重载同时创建 const 和非 const 方法。例如,如果您定义T const& operator[] (unsigned i) const;,那么您可能还需要由以下给出的非常量版本:

              inline T& operator[] (unsigned i) { return const_cast<char&>( static_cast<const TYPE&>(*this)[](i) ); }

            Afaik,C 中没有 const 函数,非成员函数本身在 C++ 中不能是 const,const 方法可能有副作用,编译器不能使用 const 函数来避免重复的函数调用。事实上,即使是一个简单的 int const &amp; 引用也可能见证它所引用的值在其他地方发生了变化。

            【讨论】:

              【解决方案13】:

              简单易记:

              如果 const 在 * 之前,则 value 是常量。

              如果 const 在 * 之后,则地址是常量。

              如果 const 在 * 之前和之后都可用,那么 value 和 address 都是常量。

              例如

              1. int * 常量变量; //这里的地址是不变的。

              2. int 常量 * 变量; //这里的值是常数。

              3. int const * const var; // 值和地址都是常量。

              【讨论】:

                【解决方案14】:

                C 和 C++ 声明语法一再被原始设计者描述为失败的实验。

                相反,让我们命名类型“指向Type的指针”;我就叫它Ptr_

                template< class Type >
                using Ptr_ = Type*;
                

                现在Ptr_&lt;char&gt; 是指向char 的指针。

                Ptr_&lt;const char&gt; 是指向const char 的指针。

                const Ptr_&lt;const char&gt; 是一个const 指向const char 的指针。

                【讨论】:

                • 你有第一句话的报价吗?
                • @sp2danny:谷歌搜索“C 语法失败的实验”只会咳出一些对 Bjarne Stroustrup 的采访,他在那个方向表达了他的意见,例如在 Slashdot 采访中“我认为 C 声明符语法是一个失败的实验”。因此,对于 C 的原始设计者的观点,我没有任何参考依据。我想可以通过足够强大的研究工作来找到它,或者仅仅通过询问他们就可以反驳,但我认为现在这样更好。声明的那一部分,仍未决定,可能是真的:)
                • “C 和 C++ 声明语法一再被原始设计者描述为失败的实验。” C 错了,请更改您对 C 的句子或提供一些引号。
                • @Stargateur:显然你已经阅读了前面的 cmets 并找到了一些你可以用来学究气的东西。祝你生活愉快。无论如何,像我这样的老前辈记得很多,如果不进行非常耗时的研究,我们就无法证明。你可以相信我的话。
                • @Stargateur "Sethi (...) observed that many of the nested declarations and expressions would become simpler if the indirection operator had been taken as a postfix operator instead of prefix, but by then it was too late to change." 来自 DMR。当然,DMR 并没有发明 const 和 volatile 关键字,它们来自 C++ / X3J11,正如该页面所证明的那样。
                【解决方案15】:

                两边都有 int 的 const 将使 指针指向常量 int

                const int *ptr=&i;
                

                或:

                int const *ptr=&i;
                

                * 之后的const 将使指向 int 的常量指针

                int *const ptr=&i;
                

                在这种情况下,所有这些都是指向常量整数的指针,但这些都不是常量指针:

                 const int *ptr1=&i, *ptr2=&j;
                

                在这种情况下,所有都是指向常量整数的指针,而 ptr2 是指向常量整数的常量指针。但是 ptr1 不是常量指针:

                int const *ptr1=&i, *const ptr2=&j;
                

                【讨论】:

                  【解决方案16】:
                  • 如果const*左边,它指的是值(不管是const int还是int const
                  • 如果const*的右边,它指的是指针本身
                  • 可以同时是两个

                  很重要的一点:const int *p 不代表你所指的值是不变的!!。这意味着您无法通过该指针 更改它(也就是说,您无法分配 $*p = ...`)。值本身可能会以其他方式更改。例如

                  int x = 5;
                  const int *p = &x;
                  x = 6; //legal
                  printf("%d", *p) // prints 6
                  *p = 7; //error 
                  

                  这主要用于函数签名,以保证函数不会意外更改传递的参数。

                  【讨论】:

                    【解决方案17】:

                    这主要涉及第二行:最佳实践、分配、函数参数等。

                    一般做法。尝试尽你所能制作const。或者换一种说法,让所有东西都以const 开头,然后准确地删除允许程序运行所需的最小consts 集。这将大大有助于实现 const 正确性,并有助于确保当人们尝试分配不应该修改的东西时不会引入细微的错误。

                    避免 const_cast 像瘟疫一样。它有一两个合法的用例,但它们很少而且相差甚远。如果您尝试更改 const 对象,您最好先找到声明它的人 const 并与他们讨论此事以就应该发生的事情达成共识。

                    这非常巧妙地引导到作业中。只有当它是非常量时,你才能分配给它。如果您想分配给 const 的东西,请参见上文。请记住,在声明 int const *foo;int * const bar; 中不同的是 const - 这里的其他答案已经很好地涵盖了这个问题,所以我不会深入讨论。

                    功能参数:

                    按值传递:例如void func(int param) 在呼叫站点,您不在乎一种或另一种方式。可以说存在将函数声明为void func(int const param) 的用例,但这对调用者没有影响,仅对函数本身有影响,因为在调用期间,函数不能更改传递的任何值。

                    通过引用传递:例如void func(int &amp;param) 现在它确实有所作为。正如刚刚声明的那样,func 被允许更改param,任何调用站点都应该准备好应对后果。将声明更改为void func(int const &amp;param) 会更改合同,并保证func 现在不能更改param,这意味着传入的内容将会返回。正如其他人所指出的,这对于廉价地传递您不想更改的大型对象非常有用。传递引用比通过值传递大对象便宜很多。

                    通过指针传递:例如void func(int *param)void func(int const *param) 这两个几乎是它们的参考对应物的同义词,但需要注意的是,被调用函数现在需要检查 nullptr,除非其他一些合同保证保证 func 它永远不会收到 @987654341 @在param.

                    关于该主题的意见。在这种情况下证明正确性非常困难,犯错太容易了。所以不要冒险,总是检查nullptr的指针参数。从长远来看,您将避免痛苦和痛苦,并且很难找到错误。至于检查的成本,它非常便宜,而且在编译器内置的静态分析可以管理它的情况下,优化器无论如何都会忽略它。打开 MSVC 的链接时间代码生成,或 GCC 的 WOPR(我认为),你会得到它的程序范围,即即使在跨越源代码模块边界的函数调用中。

                    在一天结束时,以上所有内容都提供了一个非常可靠的案例,即始终更喜欢对指针的引用。他们只是更安全。

                    【讨论】:

                      【解决方案18】:

                      只是为了 C 的完整性,遵循其他解释,对于 C++ 不确定。

                      • pp - 指向指针的指针
                      • p - 指针
                      • 数据 - 指向的东西,在示例中x
                      • 粗体 - 只读变量

                      指针

                      • p 数据 - int *p;
                      • p 数据 - int const *p;
                      • p 数据 - int * const p;
                      • p 数据 - int const * const p;

                      指向指​​针的指针

                      1. pp 数据 - int **pp;
                      2. pp p 数据 - int ** const pp;
                      3. pp p 数据 - int * const *pp;
                      4. pp 数据 - int const **pp;
                      5. pp p 数据 - int * const * const pp;
                      6. pp p 数据 - int const ** const pp;
                      7. pp p 数据 - int const * const *pp;
                      8. pp p 数据 - int const * const * const pp;
                      // Example 1
                      int x;
                      x = 10;
                      int *p = NULL;
                      p = &x;
                      int **pp = NULL;
                      pp = &p;
                      printf("%d\n", **pp);
                      
                      // Example 2
                      int x;
                      x = 10;
                      int *p = NULL;
                      p = &x;
                      int ** const pp = &p; // Definition must happen during declaration
                      printf("%d\n", **pp);
                      
                      // Example 3
                      int x;
                      x = 10;
                      int * const p = &x; // Definition must happen during declaration
                      int * const *pp = NULL;
                      pp = &p;
                      printf("%d\n", **pp);
                      
                      // Example 4
                      int const x = 10; // Definition must happen during declaration
                      int const * p = NULL;
                      p = &x;
                      int const **pp = NULL;
                      pp = &p;
                      printf("%d\n", **pp);
                      
                      // Example 5
                      int x;
                      x = 10;
                      int * const p = &x; // Definition must happen during declaration
                      int * const * const pp = &p; // Definition must happen during declaration
                      printf("%d\n", **pp);
                      
                      // Example 6
                      int const x = 10; // Definition must happen during declaration
                      int const *p = NULL;
                      p = &x;
                      int const ** const pp = &p; // Definition must happen during declaration
                      printf("%d\n", **pp);
                      
                      // Example 7
                      int const x = 10; // Definition must happen during declaration
                      int const * const p = &x; // Definition must happen during declaration
                      int const * const *pp = NULL;
                      pp = &p;
                      printf("%d\n", **pp);
                      
                      // Example 8
                      int const x = 10; // Definition must happen during declaration
                      int const * const p = &x; // Definition must happen during declaration
                      int const * const * const pp = &p; // Definition must happen during declaration
                      printf("%d\n", **pp);
                      

                      N 级解引用

                      继续前进,但愿人类将你逐出教会。

                      int x = 10;
                      int *p = &x;
                      int **pp = &p;
                      int ***ppp = &pp;
                      int ****pppp = &ppp;
                      
                      printf("%d \n", ****pppp);
                      

                      【讨论】:

                        【解决方案19】:
                        1. const int* - 指向常量 int 对象的指针。

                        你可以改变指针的值;你不能改变int对象的值,指针指向。


                        1. const int * const - 指向常量 int 对象的常量指针。

                        您不能更改指针的值,也不能更改指针指向的int 对象的值。


                        1. int const * - 指向常量 int 对象的指针。

                        这个语句相当于1.const int*——你可以改变指针的值但是你不能改变指针指向的int对象的值。


                        其实还有第四种选择:

                        1. int * const - 指向 int 对象的常量指针。

                        您可以更改指针指向的对象的值,但不能更改指针本身的值。指针将始终指向同一个 int 对象,但此 int 对象的值可以更改。


                        如果您想确定某种类型的 C 或 C++ 构造,您可以使用 David Anderson 制作的Clockwise/Spiral Rule;但不要与 Ross J. Anderson 制作的 Anderson`s Rule 混淆,这是非常不同的东西。

                        【讨论】:

                          【解决方案20】:

                          简单的助记符:

                          type 指针 * -> 指针 name


                          我喜欢将int *i 视为声明“i 的取消引用是int”;在这个意义上,const int *i 表示“i 的 deref 是 const int”,而 int *const i 表示“const i 的 deref 是 int”。

                          (这样思考的一个危险是它可能会导致偏爱int const *i 声明风格,人们可能会讨厌/不允许)

                          【讨论】:

                            【解决方案21】:

                            很多人都答对了,我会在这里整理好并添加一些在给定答案中缺少的额外信息。

                            Const 是 C 语言中的关键字,也称为限定符。常量可以 应用于任何变量的声明以指定它的值 不会改变

                            const int a=3,b;
                            
                            a=4;  // give error
                            b=5;  // give error as b is also const int 
                            
                            you have to intialize while declaring itself as no way to assign
                            it afterwards.
                            

                            如何阅读?

                            只需从右到左阅读每条语句即可顺利运行

                            三个主要的事情

                            type a.    p is ptr to const int
                            
                            type b.    p is const ptr to int 
                             
                            type c.    p is const ptr to const int
                            

                            [错误]

                            if * comes before int 
                            

                            两种

                            1. const int *
                            
                            2. const const int *
                            

                            我们先看

                            主要类型 1. const int*

                            在 3 个地方安排 3 件事情的方法 3!=6

                            我。 * 在开始时

                            *const int p      [Error]
                            *int const p      [Error]
                            

                            ii. const 开始

                            const int *p      type a. p is ptr to const int 
                            const *int p      [Error]
                            

                            iii. int 开始

                            int const *p      type a. 
                            int * const p     type b. p is const ptr to int
                            

                            主要类型2. const const int*

                            在 2 个相似的 4 个地方安排 4 个东西的方法 4!/2!=12

                            我。 * 在开始时

                            * int const const p     [Error]
                            * const int const p     [Error]
                            * const const int p     [Error]
                             
                            

                            ii. int 开始

                            int const const *p      type a. p is ptr to const int
                            int const * const p     type c. p is const ptr to const int
                            int * const const p     type b. p is const ptr to int
                            

                            iii. const 开始

                            const const int *p     type a.
                            const const * int p    [Error]
                            
                            const int const *p      type a.
                            const int * const p     type c.
                            
                            const * int const p    [Error]
                            const * const int p    [Error]
                            

                            合二为一

                            输入一个。 p 是指向 const int (5)

                            const int *p
                            int const *p
                            
                            int const const *p
                            const const int  *p
                            const int  const *p
                            

                            输入 b。 p 是 const ptr 到 int (2)

                            int * const p
                            int * const const p;
                            

                            键入 c。 p 是 const ptr 到 const int (2)

                            int const * const p
                            const int * const p
                            

                            只是简单的计算

                            1. const int * p        total arrangemets (6)   [Errors] (3)
                            2. const const int * p  total arrangemets (12)  [Errors] (6)
                            

                            一点额外的

                            int const * p,p2 ;

                            here p is ptr to const int  (type a.) 
                            but p2 is just const int please note that it is not ptr
                            

                            int * const p,p2 ;

                            similarly 
                            here p is const ptr to int  (type b.)   
                            but p2 is just int not even cost int
                            

                            int const * const p,p2 ;

                            here p is const ptr to const int  (type c.)
                            but p2 is just const int. 
                            

                            完成

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2017-01-30
                              • 2020-08-03
                              • 1970-01-01
                              相关资源
                              最近更新 更多