C++笔记(二)~const | constexpr | 类型别名 |auto

举报
海轰Pro 发表于 2022/08/26 16:33:34 2022/08/26
【摘要】 const指针定义:指针是一个常量,初始化后,指针(存放这个指针的地址值)就不可以改变了。示例代码#include<iostream>using namespace std;int main(){ int i=1; // 这句话可以看出在 int *p=&i 上面又加了一层含义:这个指针是常量 初始化后就不可以改变了 int *const p=&i; cout...

const指针

定义:指针是一个常,初始化后,指针(存放这个指针的地址值)就不可以改变了。

示例代码

#include<iostream>
using namespace std;
int main(){
    int i=1;

    // 这句话可以看出在 int *p=&i 上面又加了一层含义:这个指针是常量 初始化后就不可以改变了
    int *const p=&i;
    
    cout<<"i="<<i<<endl;
    // 用法还是和原来*p一样 只是常量化 不可以更改了
    cout<<"*p="<<*p<<endl;
    return 0;
}

运行结果


顶层const与底层const

  • 顶层const:指针本身是常量。更一般的说,顶层const可以表示任意的对象是常量
  • 底层const:指针指向的对象是一个常量


解释:指针自身就是一个对象,同时也可以指向其他对象。区分顶层const与底层const就是依据:指针自身是否是常量。若是常量,则是顶层const;反之,则是底层const。对于顶层const,要求可以放宽,不一定必须要求指针是常量,因为指针也是对象,所以顶层const更加一般的定义就是:对象是常量。

示例代码

#include<iostream>
using namespace std;
int main(){
    int i=0;
    int *const p1=&i;//顶层const
    const int ci=42;//顶层const 属于其一般定义:顶层const可以表示任意的对象是常量
    const int *p2=&ci;//底层const,因为ci定义为:const int ci
    const int *const p3=p2;//左边const是底层const 右边const是顶层const
    return 0;
}
// 代码解释

// int *const p1 是在int *p1 上面的变形,强调此时的指针是常量
// const int ci=42 是在 int ci=42 上面的变形,强调此时的ci是int类型,且为常量

// const int *p2=&ci 解释:因为ci就是const(常量),所以其指针也必须是对应的常量 
// 假设是 int ci=42 那么对应指针为:int *p2=&ci 
// 而此时ci确实 const int  所以对应的指针也应该在最前面加上const: const int *p2=&ci

// const int *const p3=p2 是在 const int *p3的变形
// 因为指针p2的定义就是 const int *p2
// 如果此时我需要用另一个指针来替代p2 
// 所以定义为 const int *p3=p2 (对应原则)
// 这时候p3指针和p2指向同一个对象ci,如果我们又希望p3是一个常量指针
// 所以定义为:const int *const p3=p2
// *const意思就是:这个指针是const常量


常量表达式

定义:值不会改变且在编译过程就能得到计算结果的表达式

示例代码

   const int max=1;//是常量表达式
   const int p=max+1;//是常量表达式
   const int q=get()//不是常量表达式 需要运行get()函数后才可以得到值


constexpr

定义:是一种类型,便于编译器验证变量值是否为常量表达式。一般来说,如果认为一个变量是常量表达式,那么就可以把它声明为constexpr类型。

示例代码

constexpr int max=1;
constexpr int p=max+1;
constexpr int se=size();// 这里需要确定size同样也是一个constexpr类型的函数才是正确的


注意:如果constexpr声明中定义了一个指针,那么限定符constexpr仅对指针有效,与指针所值的对象无关

示例代码

#include<iostream>
using namespace std;
#define constexpr const
int main(){
    const int *p=nullptr;//p是一个指向int型常量的指针 底层const
    constexpr int *q=nullptr;//q是一个指向int型的常量指针 顶层const
    return 0;
}


类型别名

定义:某种类型的别名,比如int类型,我们可以用x作为它的别名,在有x的地方就相对于int类型。


定义类型别名的两种方法

  • 使用关键字typedef
  • 使用别名声明 using


方法一:使用关键字typedef

typedef int x;//x是int的同义词
typedef x base,*p;// base是x的同义词,也就是int的同义词 p是int* 的同义词

测试代码

#include<iostream>
using namespace std;
int main(){
    typedef int x;
    typedef x y,*p;
    int a=0;
    x b=1;// 相当于 int b=1
    y c=2;// 相当于 int c=2
    int *q=&a;// 和int* q=&a 意思一样
    p q2=&a;// 同 int *q2=&a
    cout<<"a="<<a<<endl;// a=0
    cout<<"b="<<b<<endl;// b=1
    cout<<"c="<<c<<endl;// c=2
    cout<<"*q="<<*q<<endl;// *q=0
    cout<<"*q2="<<*q2<<endl;// *q2=0
    return 0;
}

测试结果

方法二:使用别名声明 using

using x=int // 写法与typedef有区别

测试代码

#include<iostream>
using namespace std;
int main(){
    using x=int;
    using y=x;
  //  using *p=x;  这里不知道应该怎么写 达到和上一个示例typedef一样的效果
    int a=0;
    x b=1;// 相当于 int b=1
    y c=2;// 相当于 int c=2
    cout<<"a="<<a<<endl;// a=0
    cout<<"b="<<b<<endl;// b=1
    cout<<"c="<<c<<endl;// c=2
    return 0;
}

测试结果

auto

编译器自动去分析一个对象是啥类型。


注意点:

  • 一般会忽略顶层const,保留底层const
  • 如果需要auto类型是顶层const,则需要明确指出
  • 当设置一个类型为auto的引用时 初始值中的顶层常量属性仍然保留

示例代码

#include<iostream>
using namespace std;
int main(){
    int i=0;
    int &r=i;//r是i的别名
    auto a=r;// a是一个int类型 (r只是i的别名,i是int类型)
    const int ci=i,&cr=ci;
    auto b=ci;// b是一个int类型整数(auto一般会忽略顶层const)
    auto c=cr;// c是一个int类型的整数(cr只是ci的别名,该句代码意思同上)
    auto d=&i;// d是一个int类型的指针
    auto e=&ci;// e是一个指向int类型常量的指针 对常量对象取地址是底层const
    const auto f=ci;// f是一个int类型常量 若不要忽略顶层const 则手动加上const
   
    // 设置一个类型为auto的引用时 初始值中的顶层常量属性仍然保留
    auto &g=ci;// 整型常量的引用
    
    // 易错:
    auto t=0;//正确 
    //auto &h=42; //错误:不可以为非常量引用绑定字面值
    const auto &j=42;//正确:可以为常量引用绑定字面值
    return 0;
}

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。