指针和const之间的关系

 const在星号左边修饰指针的指向,在星号右边修饰指针自身

int main()
{
    int a = 10, b = 20;
    int* p1 = &a;//    *是修饰符
    *p1 = 100; //*是解引用
    const int* p2 = &a;
    //*p2 = 100; //error,const修饰了指针的指向,不能通过指针修改
    //p2 = &b; //ok
    int const * p3 = &a;
    int * const p4 = &a;
    *p4 = 100;//ok
    p4 = &b;//error,const修饰的是指针自身,不能修改
    const int* const p5 = &a;
    *p5 = 100;//error
    p5 = &b;//error
}

下面,做几个例题分析一下:

第一个:

int main()
{
    const int a = 10;
    int b = 20;
    int *p1 = &a;
    const int *p2 = &a;
    int* const p3 = &a;
    const int* const p4= &a;

代码分析:在此代码中,a为常性,即a自身的值不能被改变,p1保存a的地址,因为a是常性,所以在定义指针时,应该不能通过指针修改a的值,所以应该在*的左边加上const,表示该指针不能修改指向,因此上述代码只有p2和p4能够编译通过。  

第二个:

 int main()
{
    int a = 10, b = 20;
    const int* p = &a;
    int* s1 = p;
    const int *s2 = p;
    int* const s3 = p;
    const int* const s4= p;

代码分析:在此代码中,p的指向被修饰为常性,意味着不能通过指针修改a的值,因此,如果再定义一个指针保存p的地址时,新指针不能通过解引用进行修改,即在传递的过程中不允许能力扩张,上述代码中s2和s4可以被编译通过。

第三个:

如下,如果将p自身修饰为常性,哪些不能编译通过:

int main()
{
    int a = 10, b = 20;
    int* const p = &a;
    int* s1 = p;
    const int *s2 = p;
    int* const s3 = p;
    const int* const s4= p;
}

        首先,我们声明了一个常量指针 p 。这意味着 p 是一个指向 int的指针,并且 p本身是一个常量,即 p的值(即它所存储的地址)不能被改变,但是通过 p所指向的 int值是可以被改变的。

接下来,我们逐一分析其他指针的声明:

int* s1 = p;

        这里尝试将一个 int* const(即 p)赋值给一个 int*。由于 p`指向的 int 值可以修改(尽管 p 本身不能改变指向),这个赋值是合法的。

const int *s2 = p;

        这里将 p 赋值给一个 const int*。这意味着 s2`是一个指向常量的指针,通过 s2 不能修改所指向的 int值,但 s2可以指向不同的地址(尽管在这个例子中它不会这样做)。这个赋值也是合法的,因为 p 并不承诺通过它修改值是不允许的,只是 p 自己不能改变指向。

int* const s3 = p;

        这里尝试将 p 赋值给一个 int* const。这实际上与 p 的声明是相同的类型。因此,这个赋值是合法的,s3 将像 p 一样指向 a 的地址,并且 s3 本身也不能改变指向。

const int* const s4 = p;

        这里尝试将 p 赋值给一个 const int* const。这意味着 s4 是一个指向常量的常量指针,即 s4 指向的地址不能改变,且通过 s4 指向的 int 值也不能被修改。这里的问题是,虽然 p 指向的 int 值可以通过p修改(因为 `p` 不是 const int*),但 s4 作为一个 const int* 类型的指针,要求它指向的值不能被修改。这种赋值在技术上是不允许的,因为 p 允许修改它所指向的值,而 s4 不允许。然而,在C++的实践中,由于 p 并不承诺不修改指向的值(它只是自己不能改变指向),并且 s4 只是承诺不会修改这个值,这种赋值通常是被编译器接受的,因为它不会违反 s4 的任何约束(s4 只是承诺不修改值,并不关心 p 是否允许修改值)。但理论上,这种赋值可能引起理解上的混淆,因为它依赖于未明确表达的行为(即 p 实际上是否会修改值)。不过,在大多数编译器中,这个赋值是可以通过编译的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值