【C++笔记】变量和基本类型

变量和基本类型(C++Primer 5th)

字符型

  分为三种:char、signed char 和 unsigned char 。char 和 signed char并不一样,但字符的表现形式只有两种:带符号的和无符号的。

有符号与无符号

  注意: unsigned 类型和 int 类型的加法等运算。unsigned为负数时会出现异常,自动转换为无符号数。

对象

  通常情况下,对象是指一块能存储数据并具有某种类型的内存空间。

初始化

  初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

作用域

  预处理变量无视C++中作用域的规则。

extern

  如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显示地初始化变量。
  任何包含了显示初始化的声明即成为定义,如:extern double pi = 3.1416 ; //定义。
  在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。

标识符

  用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头。此外,定义在函数体外的标识符不能以下划线开头。
  int _ ;(这个是正确的)

引用

   严格来说,当使用术语“引用(reference)”时,指的是左值引用(C++11引入了右值引用)。引用为对象起了另一个名字,定义引用时,程序将引用和初始值绑定在一起,而不是将初始值拷贝给引用。
  引用类型必须初始化,初始值必须是个对象而非数值,注意要同类型。错误示范:int &refVal =10;

指针

  指针和引用的对比:1、指针本身就是一个对象。2、指针无须在定义时赋初值。

  C++11标准下,空指针最好使用nullptr,同时尽量避免使用NULL。

  不能直接操作 void* 指针所指的对象。

int ival = 42 ;                 // 指向必须同类型
int *p = &ival;                 // p存放变量ival的地址,或说p是指向变量ival的指针。
int **pi = &p;                  // pi指向一个int型的指针,表示指向指针的指针

int *p = nullptr ;              // 等价于int *p =0 ;

int* p1,p2 ;                    // 注意p1为指针,p2为int变量

int *&r = p;                    // r是一个对指针p的引用
const

  const对象必须初始化。默认情况下,const对象被设定为仅在文件内有效。
  顶层const(top-level const)表示指针本身是个常量,底层const(low-level const)表示指针所指的对象是一个常量。

// const引用
const int ci = 1024;
const int &r1 = ci;             // 正确引用,引用及其对象都是常量
int &r2 = ci;                   // 错误引用,试图让非常量引用指向一个常量对象

int &r = 0 ;                    // 错误
const int &r = 0;               // 正确

// const指针
int errNumb =0;
int *const curErr = &errNumb;   // curErr将一直指向errNumb,可以通过*curErr修改errNumb的值

const double pi = 3.14159;
const double *const pip = π  // pip是一个指向常量对象的常量指针,不能通过*pip修改pi的值

const int *p;                   // 合法,但p没有指向任何实际的对象

// 顶层const OR 底层const
int i =0;
int *const p1 = &i;             // 顶层const,p1的值不能改变
const int ci = 42;              // 顶层const,ci的值不能改变
const int *p2 = &ci;            // 底层const,p2的值允许改变
const int &r = ci;              // 底层const,用于声明引用的const都是底层const
constexpr

  C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。

constexpr int mf = 20;          // 20是常量表达式
constexpr int limit = mf + 1;   // mf + 1 是常量表达式    
constexpr int sz = size();      // 仅size()是constexpr函数时才正确

constexpr const int *p = &i;    // p是常量指针,指向整型变量i
constexpr int *p1 = &j;         // p1是常量指针,指向整数j
类型别名

  传统的方法是使用关键字 typedef,新标准使用别名声明即关键字using来定义别名。

typedef double wages;           // wages是double的别名
typedef wages base,*p;          // base是double的别名,p是double*的别名

using SI = Sales_items;         // SI是Sales_item的别名

auto

  C++新标准引入了auto类型说明符,auto让编译器通过初始值来推算变量的类型,因此,auto定义的变量必须有初始值。
  一条声明语句中,所有变量的初始基本数据类型必须保持一致。
  auto一般会忽略掉顶层const,同时保留底层const,如对常量对象取地址是一种底层const。

auto item = val1+val2;          // 初始化

auto i = 0, *p = &i;            // 正确:i是整数,p是整型指针
auto sz =0, pi = 3.14;          // 错误:sz和pi的类型不一致 

auto c = &ci;                   // c是一个指向整数常量的指针,底层const
const auto f = ci;              // 顶层const
auto &n =i,*p2 = &ci;           // 错误:i 是 int,而 &ci 是 const int
decltype

  作用是选择并返回操作数的数据类型,不计算表达式的值(与auto不同),意思是,从表达式类型推断要定义的变量类型,同时又不希望用该表达式的值初始化变量。
  需要指出的是,引用从来都作为其所指对象的同义词,只有用在decltype处是个例外。
  decltype的表达式如果是加上了括号的变量,结果将是引用。

decltype(f()) sum = x;          // sum的类型就是函数f的返回类型

const int ci = 0,&cj = ci;
decltype(ci) x = 0;             // x的类型是const int
decltype(cj) y = x;             // y的类型是const int&,y是引用,必须初始化
decltype(cj+0) a;               // 正确,类型为int,r为表达式r+0的一部分

int i = 42;
decltype((i)) b;                // 错误,b为引用,即int&,必须初始化
decltype(i) c;                  // 正确,c为一个未初始化的int

auto和decltype的区别主要有三个方面:
第一,auto类型说明符用编译器计算变量的初始值来推断其类型,而decltype虽然也让编译器分析表达式并得到它的类型,但是不实际计算表达式的值。
第二,编译器推断出来的auto类型有时候和初始值的类型并不完全一样,编译器会适当地改变结果类型使其更符合初始化规则。例如, auto —般会忽略掉顶层const,而把底层const保留下来。与之相反,decltype会保留变量的顶层const。
第三,与auto不同,decltype的结果类型与表达式形式密切相关,如果变量名加上了一对括号,则得到的类型与不加括号时会有不同。如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量的类型;如果给变量加上了一层或多层括号,则编译器将推断得到引用类型。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值