C++ 变量与基本类型

void 空类型不对应具体的值
算数类型整型和浮点型

基本类型

类型含义size
bool布尔类型未定义
char字符8位
wchar_t宽字符16位
char16_tUnicode字符16位
char32_tUnicode字符32位
short短整型16位
int整型至少16位
long长整型至少32位
long long长整型64位
float单精度浮点型6位有效数字
double双精度浮点型10位有效数字
long double扩展精度浮点型10位有效数字
size_t机器相关的无符号类型足够大
  • 带符号signed和无符号unsigned

    • int temp;           //-2,147,483,648 to 2,147,483,647
      unsigned int temp;  //0 to 4,294,967,295
      //char
      char str;
      signed char str;    //char 与 signed char 并不一样
      unsigned char str;  //0 to 255
  • 浮点型

    • 以符号位+ 有效数字+指数位的形式存

      • 有效数字:1<M<2: 保存时舍弃第一位默认为1,读取时在第一位的位置补上1

      • 指数:0~127表示指数为负, E = e + 127 e为真实指数值

      • 表示的最小正数:0 0000 0000 000 0000 0000 0000 0000 0001

    • 例子
      float88.8125 = 101 1000.1101 == 1.0110001101×2^6
      符号位(1位)指数域(8位)小数域(23位)
      0E=6+127=133=1000 01010110001101
      double
      符号位(1位)指数域(11位)小数域(52位)

Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码。
<a name ="unicode"></a>

类型转换

有关联的两种类型之间可以相互转换

隐式转换:根据类型转换规则将运算对象类型统一后在计算,--尽可能减少精度损失

  • 大多表达式中,比int小的整型值提升到较大的整型 -- 整型提升

  • 无符号类型的运算

    • 无符号类型不小于带符号:带符号类型转换为无符号 -- 带符号的负数

    • 无符号类型小于带符号: 取决于机器

  • 条件语句中,非布尔值转换为布尔值

  • 初始化:初始值转为变量的值,赋值语句中,右侧对象转换为左侧对象的类型

  • 算数运算

  • 函数调用

  • 其他类型

    • 数组转换为指针:数组自动转换为指向数组首元素的指针 --例外

    • 指针的转换

      • 常量整数值 0 或者 nullptr 能够转换为任意指针类型

      • 指向任意非常量的指针能够转换为void* --void指针

      • 指向任意对象的指针能够转换为const void*

    • 转换成布尔类型:非零为真(算数类型、指针类型)

    • 转换成const:能够将指向T的指针或者引用转换成指向const T的指针和引用

      // T表示一种类型
      T i;
      const T &j = i;  //非常量转换为const T的引用
      const T *p = &i; // 非常量地址转换为const地址
      int &r = j; //错误,不允许const转换成非常量
    • 类定义的转换:

       while(cin>> s)


整型提升在表达式计算时,各种整型首先要提升为int类型,如果int类型不足以表示的话,就需要提升为unsigned int类型,然后再执行表达式的运算,较大的宽字符等类型,提升成能够容纳原类型值的最小的类型


数组作为取址符(&)、sizeof 以及tydeid的运算对象、关键字decltype的参数、或引用初始化数组

显示转换:强制类型转换cast

  • C风格:

    (type_name) expression type(expression)
  • C++:

    cast-name<type>(expression)
    //cast-name:static_cast dynamic_cast const_cast reinterpret_cast
    • static_cast: 任何具有明确定于的类型转换都能使用,不包括底层const,不警告潜在的精度丢失

    • dynamic_cast

    • const_cast : 用于改变运算对象的底层const

      • const char *pc;                 //底层const
        char *p = const_cast<char*>(pc);//正确
        const_cast<string>(pc)          //错误 只能改变常量属性 “去掉const性质”
    • reinterpret_cast : 本质上依赖机器、运算符并不会改变括号中运算对象的值,而是对该对象从位模式上进行重新解释

字面值常量

字面值常量的形式和值决定了 它的数据类型

  • 整型字面值

    • short类型没有相应的字面值

    进制符号类型
    十进制20带符号数int long longlong中最小的
    八进制,以0开头024不确定int long longlong uint ulong ulonglong
    十六进制,以0x开头0x16不确定int long longlong uint ulong ulonglong
  • 浮点型字面值:3.14;3.14E0; 0.; 0e0; .001默认为double类型,7.8ffloat类型

  • 布尔:true 、false; 指针: nullptr;

  • 字符和字符串字面值:两个字符串位置紧邻且仅由空格缩进换行符分隔,实际上他们是一个整体。

  • 转义序列

    • 转义序列含义指定字面值类型
      \\字符前缀 u’C‘char16_t
      ''字符前缀 U’c‘char32_t
      ""字符前缀 L'C'wchar_t
      \??字符前缀 u8字符串字面常量 char
      \a警报铃声后缀
      \b退格键u or Uunsigned
      \f换页符l or Llong
      \n换行符ll or LLlong long
      \r回车f or Ffloat
      \t水平制表符l or L 浮点型long double
      \v垂直制表符
      \ooo一到三位的八进制数 数字部分表示字符对应的数字
      \xhh一到多位的十六进制数

变量

提供一个有名字的,能够供程序操作的存储空间 -- 对象

  • 变量的初始化:对象在创建时获得了一个特定的值。初始化不是赋值。

    • 列表初始化:

      int temp = 0;
      int temp ={0}; //列表初始化
      int temp {0};
      int temp(0);
      ​
      long double ld = 3.14159;
      int temp = {ld};  //错误
    • 默认初始化:

      • 内置类型:定义在任何函数体外被初始化为0, 定义在函数体内将不被初始化-不确定的值

      • 类的对象如果没有初始化,值由类确定

  • 变量是声明和定义:变量能且只能被定义一次,可以被多次声明。 -- 多文件中使用同一个变量

    extern int temp; //声明temp而没有定义temp
    int temp; //声明且定义
    extern int temp = 0;  //定义temp: 任何包含显示初始化的声明即为定义
    ​
    void func(){
        extern int temp = 0;   //在函数体内尝试初始化由extern标记的变量:错误
    }

复合类型

引用:为了另一个已经存在的对象起的另外一个名字,引用必须初始化。

  • 引用即别名:对引用的操作都是在与子绑定的对象上进行,不能定义引用的引用

  • 引用的定义初始化: - 不允许随意改变引用所绑定的对象- 必须初始化

    • 引用的类型必须与所引用对象的类型一样 -例外

    • 初始化值是左值-

    • 初始化值不是左值:只能对const T&(常量引用)赋值

      • 临时对象只能对const T&(常量引用)赋值

    • 引用不是对象,没有实际地址 -不能用来初始化指针

    const double& cdr = 1; // okint i=100, i2 = 22;
    int &r =i, j = i2;
    ​
    int &temp =10; //错误,引用的初始值必须为对象
    double d2 = 1.;
    int &temp = d2; //错误,引用的类型必须于引用的对象严格匹配
    ​
    double& dr = 1; // 错误:需要左值
    const double& cdr = 1; // ok
    ​
    T1 func(T2& temp);  //函数声明
    T2 fun2();          //函数声明
    func(func2());      //错误, 函数返回值为临时对象,不能用来初始化非常量引用

允许使用任意表达式初始化常量引用、只要表达式的结果能够转换为引用的类型:{非常量的对象、字面值、一般表达式}

指针:本身就是一个对象,允许对指针赋值和拷贝,无须在定义时初始化,

块作用域{}中定义未初始化将拥有不确定的值

  • 定义 int *p, *d; int *d = & val - &取值符

  • 指针的值: 指向一个对象、指向紧邻对象所占空间的下一个位置、空指针、无效指针

  • 解引用符: *d,适用于确实指向对象的指针·

  • 建议初始化所有的指针:

取值符与解引用符:

取地址符(&)返回的是int *类型,如int *p = &a

解引用符(*)返回的是int &类型,

int ival = 1024;
int * p1 = 0;  //空指针
int * p2 = & ival;
if(p1)  //条件的值为false, 非空为真
if(p2)  //条件的值为true 
 p1 == p2;  //false 两指针存放的地址值相等:1.都为空、2.指向同一个对象、3.指向同一对象的下一地址
p1 != p2;   //true;
  • void* 指针

    特殊的指针类型,能够存放任意对象的地址

    double obj = 3.14;
    void * p = obj;
    ​
    *p =9.87;  //错误:不能直接操作void*指针所指的对象
    ​
    double * dp = static_cast<double*>(p);  //显示类型转换找回指针类型

复合类型的声明

int *p1,p2; //p1是指向int的指针、p2是int类型
int **p3 = &p1;  //p3是指向指针(p1)的指针
int *&r = p1;   //r是指向指针(p1)的应用

常量表达式 -C++11

  • 指值不会改变且在编译过程就能得到计算结果的表达式 -普通函数初始化的变量不属于常量表达式

  • constexpr变量:变量是一个常量表达式,就声明成 constexpr int size = 100; -能够用特殊的constexpr函数初始化constexpr变量

  • 指针和constexpr

    const int *p = nullptr;     //底层const: 指向整型常量的指针
    constexpr int *q = nullptr; //置为顶层const: 指向整型的常量指针
    //同const指针一样,constexper指针即可以指向常量也可以指向非常量 
    ​
    constexpr int *np = nullptr;
    int j = 0
    constexpr int i = 42;
    // i和j必须定义在函数体外面
    constexpr const int *p = &i;  //p是常量指针,指向整型常量i
    constexpr int * pi = &j;     //pi是常量指针,指向整型j

处理类型

类型别名

  • 某种类型的别名,定义方法 - 关键字typedef,新方法 别名声明

    typedef double wages; // wages 是double 的别名
    
    using int32_t = int; //int32_t是int的别名
  • 指针、常量和类型别名

    typeded char* pstring;
    const pstring cstr = 0;  //指向char 的常量指针,而非指向常量char的普通指针
    const pstring *ps;       //指针,指向指向char的常量指针

auto 类型说明符(C++11)

  • 让编译器通过初始值来推断变量的类型

  • 一般会忽略掉顶层const(auto 引用时,初始值中顶层const属性会保留),保留底层const ,

  • 如果希望推断出来的类型为顶层const ,需明确指出

    auto i = 0, *p = &i;   //正确:i是整数、p是整型指针
    auto sz = 0, pi = 3.14; //错误,sz 和pi类型不一样
    ​
    const int ci = i, &cr = ci;
    auto b = ci;    // ci的const 被忽略了
    auto c = cr;    // c是整数
    auto d = &i;    //整型指针
    auto e = &ci;   //指向常量整数的指针(对常量对象取址是一种底层const)
    const auto f = ci; // f类型为 const int
    auto &g = ci;    //整型常量引用
    auto &h = 42;    //错误
    const auto &j = 42; 
    ​
    auto &n = i, *p = &ci;   //错误,i类型为int,ci类型为const int,初始值必须是统一类型

decltype 类型指示符(C++11)

  • 选择并返回操作数的类型-取值符与解引用符

  • decltype((variable)) 的结果永远是引用(双括号)

    const int ci = 0, &cj = ci; //cj: const in&
    decltype(ci) x = 0;         //const int
    decltype((ci)) x2 = x;      //const int&, 必须初始化
    decltype(cj) y = x;         //const int&, 必须初始化
    //表达式
    int i = 43, *p = &i, &r = i; 
    decltype(r+0) b;   //正确,加法的结果是int,获得引用的类型
    decltype(*p) c;   //错误,c是int&   -- 解引用符* 返回的是 int &; 

    参考

  • cppreference.com
  • 《C++ Primer》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值