6const

发布时间 2024-01-11 23:11:10作者: 二氧化硅21

const

怎么理解const?

  • const修饰的变量不能再作为左值。即初始化后不能被修改。

C和C++中的const有什么区别?

  • C中const量可以只定义,但不被初始化(之后无法再赋值),称作常变量。事实上,通过指针仍可修改变量的值。

  • C++中的const必须初始化,称作常量。通过指针不可修改变量的值。

  • C和C++中对const变量的编译方式不同,C中const当作一个变量编译生成;C++中出现const常量名字的地方,都被常量的初始值替换,包括*(&a)这样的形式,也是直接当作a,替换。事实上,a所处的内存上的值已经被替换。

  • 如果C++中const初始化为另一个变量,也是常变量。

    int main()
    {
        const int a = 2;
        int arr[a];  //a是常变量,报错
        int* p = (int *) & a;
        *p = 20;
        cout << a << endl << *p << endl << *(&a); //三者都是20。
    }
    
    int main()
    {
        const int a = 2;
        int arr[a];  //a是常量,没问题
        int* p = (int *) & a;
        *p = 20;
        cout << a << endl << *p << endl << *(&a); //a依然是2,*p是20,*(&a)依然是2。
    }
    
    int main()
    {
        int c = 5;
        const int d = c; //即使是在C++中,这种初始化const变量的方式也只生成常变量。
        cout << d << endl;
        int* p = (int*)&d;
        *p = 4;
        cout << d << endl; //可以被修改。
    }
    

const修饰的量常出现错误:

  • 常量不能直接作为左值(不可直接修改)
  • 不能把常量的地址泄露给一个普通指针或普通引用(不可间接修改)
    int main()
    {
        const int a = 5;
        int* p = &a;  //不能把const int*转换为int*,但可以int*转换为const int*
    }
    

const结合一级指针

C++语言规范:const修饰的是离它最近的类型(*不能单独作为类型)

//一般使用前两种保护常量。
const int *p; //const修饰int,即指针所指向的值,p指向内容不变,但p的指向可变。
int const *p; //const修饰int,同上。
int *const p; //const修饰int *,指针p为常量,指向不可变,但可通过指针解引用修改指向内容。
const int *const p; //p指向const int且p的指向不变。

总结:

int * <- const int *  //错误
const int * <- int *  //正确
int main()
{
    //const右面没有指针*的话,const不参与类型。二者类型皆为int *,二者也可相互赋值
    int* p1 = nullptr;
    int* const p2 = nullptr;
    p1 = p2;
    cout << typeid(p1).name() << endl;
    cout << typeid(p2).name() << endl;
}

const结合二级(多级)指针

int main()
{
    int a = 0;
    int* p = &a;
    //以下情况均错误
    //const int** q = &p; //const修饰int,二次指向的值不能变,但q,*q可被赋值。同时也把const int暴露给了*p。
    //int* const* q = &p; //const修饰前方int *,*q不能改变,但q,**q可被赋值。
    //int** const q = &p; //const修饰前方int **,q不能改变,但*q,**q可被赋值。
    const int *const* q = &p; //const修饰int和*q,即**q和*q都不能改变,q指向可改变。
    
}

总结:

int ** <- const int **  //错误
const int ** <- int **  //错误
int ** <- int* const*  //错误
int* const* <- int **  //正确

题目