【问题标题】:const qualifier and arraysconst 限定符和数组
【发布时间】:2015-08-13 06:37:02
【问题描述】:

我正在学习 C++,但我对数组有疑问(我还在研究这个主题,有些事情很清楚,而有些事情对我来说仍然有点晦涩难懂)。 我想知道这些声明是否合法,如果合法,它们如何影响新创建的数组:

假设我想创建一个整数数组(为了简单起见):

我知道以下是合法的

int array[size];

其中 size 是一个常量表达式

还有这个

const int array[size];

这个声明意味着我可以读取访问数组中的元素,但我不能分配给它们(int a=array[2] 是合法的,array[1]=10 是错误的)。

“顶级” const 怎么样

int const array[size];

const int const array[size];

它们首先是合法的吗?如果是这样,它们是什么意思?数组本身不是常量,不可能分配给数组或复制初始化一个数组吗?

谢谢!

编辑:

我知道“顶级”和“低级” const 的含义(尽管我了解到我可以将 const 限定符放在基本类型说明符之前和之后,这不会改变任何东西)。我想知道的是定义一个 const 数组(我的意思不是一个 const 对象或变量的数组)如何改变事情。

【问题讨论】:

  • int constconst int 的意思完全一样。见Const before or const after?
  • 你自己试过了吗?
  • 一个好的助记符是永远不要把const放在前面,然后const将放在常量后面(并不是说它在这里很有用,但是加上几个星号和&符号,你会看到是你的标题)。将const 放在前面与将const 放在int 后面是一样的。

标签: c++ arrays constants


【解决方案1】:

以下两条语句有效且相等,

const int a[5]={1,2,3,4,5}; 

int const a[5]={1,2,3,4,5}; 

这是初始化常量数组的方法。

下面的声明给你一个语法错误。

const int const a[5];

【讨论】:

  • 所以即使数组是复合类型,在元素的类型说明符之前或之后放置 const 也不会改变任何东西?和写 'const int' 或 'int const' 一样吗?
【解决方案2】:

根据 C++ 标准限定符 const 可以与除自身之外的任何类型说明符组合。这意味着在声明的一系列类型说明符中可能只有一个 const 限定符。类型说明符和限定符可以按任意顺序组合。

所以你可以通过以下方式声明一个整数常量数组

const int array[size] = { /* list of initializers */ }; 
int const array[size] = { /* list of initializers */ }; 
const signed array[size] = { /* list of initializers */ }; 
signed const array[size] = { /* list of initializers */ }; 
signed const int array[size] = { /* list of initializers */ }; 
int const signed array[size] = { /* list of initializers */ }; 
const int signed array[size] = { /* list of initializers */ }; 
const signed int array[size] = { /* list of initializers */ }; 
int signed const array[size] = { /* list of initializers */ }; 
signed int const array[size] = { /* list of initializers */ }; 

所有这些数组声明都是等价的。

考虑到常量对象在定义时应该被初始化。

限定符 const 也可以出现在声明符中。因此,例如以下声明声明了不同类型的对象

int const *p;
const int *p;

一方面和

int * const p = new int;
const int * const p = new( 10 );

另一方面

* 之后的第二个限定符 const 属于声明符。

还要考虑到与 C++ 中的 C 限定符相反,const 可以在类型说明符序列中多次出现。冗余限定符被忽略。

所以你可以用 C 来写例子

const signed const int const array[size] = { /* list of initializers */ }; 

【讨论】:

    【解决方案3】:

    如果你有指针,它可以是常量指针

    const int *ptr = 5;
    

    或指向常量值的指针:

    int* const ptr = 5;
    

    指向常量值的常量指针

    const int* const ptr = 5;
    

    根据定义,数组是 const 指针 - 您不能重新分配整个数组。下面的代码会导致错误:

    int array[5];
    int secondArray[5];
    secondArray = array;
    

    所以定义数组 const 不应该改变数组的可访问性(它已经是 const)。您不能更改数组元素的可访问性。

    int array[5];
    

    相似(不一样!):

    const int *array = malloc(sizeof(int)*5);
    

    然后代码:

    array[2] = 3;
    

    类似于:

    *(array+2) = 3;
    

    指针是 const 但它的值不是。

    【讨论】:

    • “根据定义,数组是 const 指针” 恕我直言,这是误导。数组是 not 指针。从历史上看,它们是从类似指针的东西演变而来的,即方式分配仍然是非法的 IIRC(这防止了 C 之前遗留代码中的某些问题)。此外,数组的常量是根据定义其元素的常量。 typedef int my_arr[10]; const my_arr x = {};,则x的类型为const int[10],其元素的类型为const int
    • @dyp:我认为在汇编级别它可能是指针;-)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 2016-01-09
    • 2019-05-10
    • 1970-01-01
    相关资源
    最近更新 更多