c++ primer

2 变量和基本类型。

2.1 变量和基本类型。

  • c++定义了一套 算术类型和空类型,算术类型主要是整型(包括bool型)和浮点型。
  • 类型转换:类型转换是有优先级的,类型所能表示的范围决定了转换的过程,“无中生有”是不行的,比如把3.14f赋值给int型的数据就只能保存期整数部分,相反的把int型的数据赋值给double的话无非是加上小数点,不能再小数点后生成数字。
  • 只有十进制,八进制,十六进制都有对应的简单表述: 20, 024, 0x14,都表示20,分别对应十进制,8进制和16进制。
  • 单引号括起来表示char字面值,双引号括出的单个或者多个字符则构成字符串。
  • 转义序列是还是比较常用的,最常用的是 \n, \t, \a, \r 分别是换行,横向制表,响铃,回车。
  • 转移后面只对三个数字其作用,比如 \1234 则便是两个字符,分别是123对应的字符以及字符 4.

2.2 变量。

  • 同一个语句中,先定义的对象经过初始化之后可以被后面的对象使用:
    eg: double price=0.9, disconut=price*0.15
  • 初始化和赋值不同,初始化的含义是在创建变量的时候给予其一个初始值,而赋值是要擦掉当前值而以一个新的值代替。
  • 列表初始化是可以的,c++11全面支持。比如:
int a=0;
int a={0};
int a(0);
int a{0};

这四种初始化方式c++11都是支持的。c++11中用花括号来初始化变量得到了全面应用。

  • 默认初始化。
    定义变量的时候没有指定初始值的话,则就会被默认初始化,这个初始化的值由变量类型决定,另外变量定义的位置也会对变量的初始化值有影响。
    规则: 定义于任何函数体之外的变量都会被初始化为0,定义在函数内部的内置类型变量将不被初始化,如果试图拷贝或者复制,将会报错!
  • 声明。
    使用extern关键字可以只表示声明而非定义,比如extern int j;就指标是声明j,在后面的代码中还可以定义int j=0;,这样都是正确的,特别的,任何进行了显式初始化的声明即成为定义,且函数内部不允许使用这样的extern关键字。变量仅能被定义一次,但可以声明多次.
  • 关于名字的作用域,是按照花括号为分割的,可以嵌套,一个建议是当第一次使用某个变量的时候在定义它,这样可以容易找到变量的定义,而且一般会赋予其一个比较合理的初始值。

2.3 复合类型。

复合类型这里主要指的是引用指针

  • 引用:引用就是别名,引用不是对象,所以引用的时候必须初始化,因为引用不是对象,所以不能定义引用的引用,也不允许赋值和拷贝。
  • 指针:指针是对象,可以进行拷贝和赋值,使用指针来访问对象的时候需要解引用符*
    空指针不指向任何对象,一个好的习惯是在使用一个指针之前检查一下其是否为空,c++11中允许使用nullptr来初始化一个指针为空。也可以使用NULL,在新的c++程序中应该避免这样使用。
    指针相等 1. 都为空 2. 指向同一个对象 3. 都指向同一个对象的下一个地址。 值得注意的是,一个指针指向某对象,一个指针指向这个对象的下一个位置,这两个指针也可能相等。
  • void 指针:可用于存放任意对象的地址,但是我们对该地址中存着什么类型的对象并不清楚。

cosnt 限定符。

  • cosnt 不允许修改,所以定义的时候必须进行初始化,另外,cosnt只在当前文件起作用,如果需要多个文件共享const,需要使用extern关键字。

  • 对于cosnt的引用就是常量引用 int x=4, cosnt &r=x; 这样的写法是没有问题的,允许将cosnt int &绑定到一个普通的int对象上。但是不允许用将普通的引用绑定到常量上:const int &r1=4; int &r2=r1*4; 这样是不合法的。

  • 常量引用仅对引用可参与的操作作出了限定,对于引用的对象本身是不做限定的,也就是说说,常量引动可以绑定常量也可以绑定非常量,但是不允许通过常量引用来修改其值,但是并没有限定不可以通过其他的方式来修改。

  • 对于指针来说是一样的,也可以令指针指向常量或者非常量,指向常量的指针不能用于修改其对象的值,所以,要想存放常量的地址,只能使用指向常量的指针。

    const double phi=3.14;
    double *ptr1=φ         //error ,ptr1 is a normal ptr!
    const double *ptr2=φ   // right! ptr2 is a const ptr!
    *ptr2=4;       //erroe, phi is a const,can not be change!
    

    和引用相同,可以另一个常量指针(指向常量的指针)来指向一个非常量,但是不能通过这个指针来修改其值!
    所谓常量指针和常量引用,都是指针或者引用“自以为是”罢了,他们觉得自己指向了常量(其实并不是),变自觉的不能通过自己来修改所指向的量的值!

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

  • constexpr 表达式:
    实际中允许将变量声明为constexpr类型的类型,由编译器来验证变量的值是否是一个常量表达式,这样声明表示变量一定是个常量,且必须由常量表达式来初始化。
    一个constexpr指针的初始值必须是nullptr或者0,或者存储于某个固定地址中的对象。(函数体内的变量一般并非存放在固定地址中,所以constexpr指针不能指向这样的变量,也就是说,定义于任何函数体之外的对象其地址是固定不变的,所以可以用来初始化constexpr指针)。必须声明:constexpr声明中如果定义了一个指针,那么限定符仅对指针有效,与指针所指的对象无关。

2.5 类型处理

  • 类型别名: typedef 这是传统的做法: typedef double wages; 那么wages就是double的同义词。
    c++11新规定了一种用法: using SI=double; 也是可以用类型别名。

  • atuo 可以推断所属类型,所以auto定义的对象必须有初始值(不要一味迷信 auto,毕竟类型不确定时,会导致代码的可读性下降)。
    auto会忽略顶层const,底层会保留

    int i=0, &r=i;
    auto a=r;          //a是一个整数
    const int ci=i; &cr=ci; 
    auto b=ci;      //b是整型,ci的顶层const被忽略。
    auto c=cr;      // c是整型,cr是ci的别名,所以和上面是完全一样的
    auto d=&i;      // &是地址,所以这就是一个整型指针。
    auto e=&ci;     // e是指向整数常量的指针,ci是一个常量,这个是一个底层cosnt,并不会被忽略。
    //如果想要希望推断出来的auto类型是一个顶层cosnt,所以需要明确指出:
    cosnt auto f=ci;     //推断出来的是cosnt int,int 是从ci推断出来的,而cosnt是限定的。
    
    
    
  • decltype.
    用来获得表达式的类型,可以当做左值来使用:

  int i=4, *p=&i, &r=i;
  decltype(r+0) b;   //r是引用,但r+0得到的结果是一个int,相当于 int b;
  decltype(*p) c;     //这个是不对的,有解引用操作得到的是引用,引用是必须初始化的。
  //双括号强制得到引用;
  decltype((i))  d;      //错误,(())得到的是引用,必须初始化
  decltype(i)  e;    //正确

待续!!

你可能感兴趣的:(c++ primer)