zoukankan      html  css  js  c++  java
  • C++基础——1.变量和基本类型(基于c++11)

    C++11类型

    基本类型

    1. 字面值常量(literal)
      比如:一个形如42的值,即为常量

    2. 变量

      • 初始值
        初始化不是赋值,初始化是创建变量的时候给一个初始值;而赋值是擦除当前值,用新值代替。
      • 列表初始化
        c++11允许使用{}来初始化变量。
        比如:
        int units_sold{0};//表示该值被初始化为0
        同理,对于vertor:
        vector<string> astr = {"abc", "is", "alphbat"};
      • 初始化方式
        itn a = 0;//使用‘=’,拷贝初始化  
        int a = {0};  
        int a{0};   
        int a(0);//不使用‘=’,直接初始化       
        
        • 拷贝初始化:
          使用‘=’
          编译器把等号右边的初始值拷贝到新创建的对象中。
          只能提供一个初始值
        • 直接初始化:
          不使用‘=’,比如int a(0)
          当初始值只有一个时,使用直接初始化或拷贝初始化都行。如果初始化需要多个值,则只能用直接初始化。
          比如:
          string str(3,'c');//str = "ccc";
        • 注意:
          如果是类内初始值,那么只能使用拷贝初始化或者花括号形式,
          一定不能使用圆括号【变量后面跟着原括号像以该变量类型和原括号内容生成的一个类】(在类中有
          string a = string('c'),带有迷惑性)
        • 初始化值为列表时,只能使用花括号进行列表初始化。
      • 默认初始化
        没有赋值的变量编译器会自动为其赋一个初值。但是,函数内定义的内置类型变量不被初始化。
      • 作用域范围
        就近定义变量原则。
    3. 复合类型

      • 引用(别名)
        • 初始化时候绑定初始值,一旦完成绑定,无法重新绑定到另一个对象。
        • 没有引用的引用
        • 只有对象才有引用
      • 指针
        • nullptr
          建议初始化所有的指针。
        • 永远记住赋值改变的是等号左边的值。
          比如:
          int *p = nullptr;      
          p = &ival;//改变的是p的内容,即存放在pi内的地址值。    
          *p = 0;//改变的是*p的内容,即p指向对象的值。
          
      • void * 指针
      • 指向指针的指针
      • 指向指针的引用
        引用不是对象,所有没有指向引用的指针。但是指针是对象,所有存在指向指针的引用。
    4. const

      • 初始化
      const int ci = i;
      int j = ci;//没有改变ci值是可以的
      
      • 默认情况下,const对象只在文件内有效
      • 多个文件使用const对象
        extern const int bufsize;
      • const的引用 = 也称为常量引用
        const int ci=1024;
        const int &r = ci;//r不能被改变
        
      • 引用的类型必须与其所引用对象的类型一致
        例外:
        • 初始化常量引用允许任意表达式作为初始值
          int i = 42;
          const int &r1 = i;
          const int &r2 = 42;
          const int &r3 = 2 * r1;
          
      • 对const的引用可能引用一个并非const的对象
        比如:
        int i=0;  
        int &r1 = i;
        const int &r2 = i;
        r1 = 3;//正确
        r2 = 4;//错误	
        
        r2绑定非常量是合法的。不允许通过r2修改绑定对象。可以类比const *int常量指针。
      • 指针与const
        • 指向常量的指针(pointer to const)
          const int *** 表示 int * **内容是常量
          不能改变其所指的对象的值
          要想存放常量对象的地址,只能使用指向常量的指针。
          const double pi = 3.14;  
          double *ptr = &pi;			//错误,用一个非常量指针指向常量对象  
          const double *cptr = &pi;	//正确,指向常量对象的地址,需要使用常量指针。  
          
          可以有这样的情况:
          double dval = 3.3;
          const double *cptr = dval;//允许,同常量引用一样,不能通过*cptr改变dval的值。 
          
        • const指针 = 常量指针 =(const point)
          int const 表示指针是常量
          指针是对象,可以把自身定义为常量。
          因为自身是常量,不允许修改,所以定义时,就要初始化。*
        • 如何区分
          从右向左读。
          int errNumb = 0;
          int *const errptr = &errNumb;//errptr永远指向errNumber,即errptr不能再指向其他对象了。
          *errptr = 3;//errNumb是非常量,可以通过*errptr改变。  
          
      • 顶层const
        表示指针本身是一个常量。
        int i = 0;
        int const* p1 = &i;//p1不能改变,是顶层
        const int c1 = 42; //c1不能改变,是顶层	
        
      • 底层const
        表示指针所指对象是一个常量。
        const int *p2 = 42;//p2可以改变,是顶层
      • 指针即可以是顶层也可以是顶层。
      • constexpr 和常量表达式
        • 常量表达式
          值不会改变并且在编译过程就能得到计算结果的表达式。
          const int max_files = 20;
          const int limit = max_files + 1;//都是常量表达式
          
        • constexpr变量
          c++11新规定,允许将变量声明为constexpr类型,由编译器来识别是不是常量表达式。
          constexpr int mf = 20;
          constexpr int limit = mf + 1;
          constexpr int sz = get_size();
          
        • constexpr声明中有定义指针,那么constexpr仅对指针有效,与指针所指对象无关。
        const int *p = nullptr;		//p是一个指向整形常量的指针(所指的内容是常量)
        constexpr int *q = nullptr; //q是一个指向整数的常量指针(指针是常量)
        
        • constexpr指针的初始化值必须是0/nullptr/固定地址。所以函数体内不能定义(对象在堆栈上,不是固定地址)。
    5. 对复杂类型的处理

      • 别名
        • typedef
          能区分
          typedef char* pstring;
          const pstring cstr = 0;
          const pstring *ps;
          
          对于const pstring cstr = 0,const是修饰谁?
          修饰char*,修饰的是指针(即是常量指针),而不是等价const char * cstr(修饰的是指针指向的内容)
          这里需要将typedef修饰的类型作为整体去看,而不是简单的替换。
          对于const pstring *ps,ps是一个指针,该指针指向char的常量指针。(二阶指针)
        • using(新规定)
          using PP = People;,用PP作为People类的别名。
      • auto(C++11引入)
        • auto让编译器通过初始值来推算变量的类型。auto的定义必须有初始值。
        • auto忽略顶层const:
          const int ci = i, &cr  = ci;
          auto b = ci;//忽略ci的顶层const,这里b是一个int类型
          auto c = cr;//cr是别名,auto声明为引用所引用对象的类型,这里c是int型。
          auto d = &i;//&i是int *,所以d是 int *;
          auto e = &ci;//&ci是对常量对象的取址(底层的const),e是指向常量对象的指针。
          
        • 希望是顶层const需要明确指出:
          const auto f=ci;
        • auto的引用
          auto &g = ci;//ci是一个整形常量,那么g是整形常量引用
          auto &h = 42;//错误,不能把非常量引用绑定到字面值
          const auto &j = 32;//正确,常量引用绑定到字面值
          
      • decltype(C++11引入)
        从表达式推出要定义的变量的类型,但是不想用该表达式的值初始化变量。
        decltype(f()) sum = x;//sum的类型是f()的返回类型
        • decltype处理顶层const和引用的方式 与 auto不同:
          const int ci = 0, &cj = ci;
          decltype(ci) x = 0;	//x是const int
          decltype(cj) y = x;	//y是const int&
          decltype(cj) z;		//z是const int&,没有初始化,错误
          
        • decltype 与 引用
          decltype使用的表达式不是一个变量,则decltype返回表达式结果对应得类型。
          int i = 42, *p = &i, &r = i;
          decltype(r+0) b;
          //decltype(r) x,x是int &,但是b是 r+0的表达式,其是r(i的别名)+0的结果的类型,所以b是int类型。  
          decltype (*p) c;
          //decltype(p) y,y是int *类型,但是decltype(*p)是解引用操作,即为int &c;错误,需要初值。 
          
        • decltype((val))和decltype()
          双括号永远是引用,单括号看值类型。
    6. 自定义结构

      • c++11支持类内初始值,之前版本不支持(被认为还没有实例,不能被赋值)。
        • c++11中没有被赋初始值的,会被赋默认值。
        • 类内初始值限制:放花括号,或等号右边。一定不能放圆括号。(圆括号是对象实例初始化使用,这里还没有对象实例)
  • 相关阅读:
    写一个列表生成式,产生一个公差为11的等差数列
    如果对方网站反爬取,封IP了怎么办?
    为什么会选择redis数据库?
    你是否了解谷歌的无头浏览器?
    遇到的反爬虫策略以及解决方法?
    常见的HTTP方法有哪些?
    遇到反爬机制怎么处理?
    列举网络爬虫所用到的网络数据包,解析包?
    python中的关键字yield有什么作用?
    如下代码输出的是什么?
  • 原文地址:https://www.cnblogs.com/jsgnadsj/p/5222199.html
Copyright © 2011-2022 走看看