转义序列**
程序员不能使用的两类字符:
(1)不可打印的字符(退格或其他控制字符,因为他们没有可视的图符)
(2)有特殊含义的字符(单引号、双引号、问号、反斜线此时就需要要用到转义字符)
在程序中转义序列被当作一个字符使用
特例:
八进制转义字符 \后带有三个0~7的数字,超过三个,则只有前三个与\构成转义序列
例:\1234表示两个字符,即八进制数123对应字符以及字符4
十六进制转义字符 \xxxxxxxx 要用到后面跟着的所有数字
变量
提供一个具名的、可供程序操作的存储空间
变量定义(定义的同时可以初始化)
形式: 类型说明符 变量名(一个或多个,以逗号分隔);
特例:
std::string book("0-201-78234-x"); //book通过string字面值初始化
列表初始化
具有多种形式
int a=0;
int a={0};
int a{0};
int a(0);
用花括号初始化变量运用广泛
当用于内置类型的变量时:如果使用列表初始化且初始值存在丢失风险时,编译器会报错
例如:
long double pi=3.1415926;
int a{pi},b={pi}; //错误,转换未执行,pi是long douible类型,a,b是int类型,发生转换会有精度损 失,存在信息丢失风险
int c(pi),d=pi; //正确,转换执行,也发生精度损失,此时c=3,d=3
变量声明和定义 (变量只能被定义一次,但可多次声明)
若想声明一个变量而非定义它,在变量名前添加extern即可,而且不要显示的初始化变量
extern int i; //声明i而非定义i
int j; //声明并定义(可初始化)
任何包含了显式初始化的声明即成了定义
extern double pi=3.1415926; //是定义,初始化抵消了extern的作用
标识符 (长度没有限制,对大小写敏感)
(1)由字母、下划线、数字组成
(2)开头必须是字母或下划线,不能是数字
(3)不能是关键字
特殊:用户自定义的标识符不能连续出现两个下划线,也不能以下划线紧连大写字母开头,此外,定义在函数体外的标识符不能以下划线开头
变量命名规范
(1)标识符要体现实际含义
(2)变量名一般用小写字母
(3)用户定义的类名一般以大写字母开头
(4)如果标识符由多个单词组成,则单词间应有明显区分,如写成 quickSort或quick_sort,不要写成quicksort
复合类型**
1.引用
为对象引了另一个名字,引用类型引用另外一种类型
通过将声明符写成&d的形式来定义引用类型,d是声明的变量
int a=123;
int &b=a; //b指向a(是a的另一个名字)
int &b; //错误,引用必须被初始化
性质:
(1)引用本身不是一个对象,不能定义引用的引用(没有实际地址,也不能定义指向引用的指针)
(2)定义了一个引用后,对其进行的所有操作都是在与之绑定的对象上进行的
(3)引用类型要和与之绑定的对象严格匹配,而且引用只能绑定在对象上,而不能与字面值或某个表达式的结果 绑在一起
典型错误:
double pi=3.14;
int &a=pi; // 类型不同,pi是double,a是int类型
int &b=1; //引用不能与字面值绑在一起
2.指针 (最好初始化所有指针,指针类型要与指向对象严格匹配)
指针值4种状态:
(1)指向一个对象
(2)指向紧邻对象所占空间的下一个位置
(3)空指针(即没有任何对象)
(4)无效指针(即上述情况下其他值)
利用指针访问对象
使用解引用符(操作符*),此操作符仅适用于那些确实指向了某个对象的有效指针
void*指针
可用于存放任意对象的地址(指针)
不能直接操作void*指针所指向的对象,因为这个对象不知道是什么类型,能做哪些操作
double pi=3.14,*p=π
void * ptr=π //pi可以是任意类型的对象,ptr可存放任意类型的指针
ptr=p;
指向指针的引用 (从右往左阅读更容易理解)
int a=1;
int *p; //p是一个int型指针
int * &r=p; //r是一个对指针p的引用
r=&i; //r引用了一个指针,因此给r赋值&i就是令p指向i
*r=0; //解引用r得到i,即p指向的对象将i的值改为0
const限定符
形式:const 数据类型 变量=值
const对象一旦创建后就不能再改变,所以const对象必须初始化
指针与const
指向常量的指针不能用于改变其所指的对象的值
const double pi=3.14159; //pi是个常量,其值不能被改变
double *ptr=π //错误,ptr是一个普通指针,pi是常量
const double *cptr=π //正确
*cptr=1; //错误,不能给*cptr赋值
可以使一个指向常量的指针指向一个非常量对象
double a=1.1; //a值可变
const double pi=3.14;
const double *p=π
p=&a; //不能通过p改变a的值
const指针 (*const)
*放在const关键字前面用来说明指针是一个常量,即不变的是指针本身值,并不是指针指向的那个值
int a=0;
int *const b=&a; //b将一直指向a
const double pi=3.14;
const double * const p=π //p是一个指向常量对象的指针
constexpr和常量表达式
const int a=0; //a是常量表达式
const int b=a+1; //b是常量表达式
int c=27; //c不是常量表达式
const int d=get_size(); //d不是常量表达式,d的值运行时才能获取
constexpr变量 (类型有所限制,必须是字面值类型)
声明为contsexpr的变量一定是常量,而且必须用常量表达式初始化
constexpr int a=0; //a是常量表达式
constexpr int b=a+1;
constexpr int d=get_size(); //只有当get_size是一个constexpr函数时才是一条正确的声明语句
指针和constexpr
一个constexpr指针的初始值必须是nullptr或0,或者是存储于某个固定地址中的对象,而且仅对指针有效与指针所指对象无关
const int *p=nullptr; //p是一个指向整型常量的指针
constexpr int *q=nullptr; //q是一个指向整数的常量指针
类型别名
-
使用typedef关键字
typedef double wages; //wages是double的同义词 typedef wages bace,*p; //base是double的同义词,p是double *的同义词
-
使用别名声明来定义类型别名
using a=Sales_item; //a是Sales_item的同义词
使用using关键字作为别名声明的开始,其后紧跟别名和等号,作用是把左侧的名字规定成等号右侧类型的别名
不能把类型别名替换成它本来的样子来理解语句的含义
指针、常量和类型别名
typedef char *pstr;
const pstr cstr=0; //cstr是指向char的常量指针 const char *cstr=0;
const pstr *p; //p是一个指针,对象是指向char的常量指针 (二级指针)
auto类型说明符 (auto定义的变量必须有初始值)
auto c=a+b; //由a+b的结果可以推算出c的类型
auto i=0;*p=&i; //正确,i是整数,p是整型指针
auto m=0;pi=3.14; //错误,m和pi类型不一致
复合类型、常量和auto
auto一般会忽略顶层const,而保留底层const
顶层const表示指针本身是个常量,底层const表示指针所指的对象是个常量
const int a=i,&m=a;
auto b=a; //b是一个整数(顶层const性质被忽略)
auto c=m; //c是一个整数
auto d=&i; //d是一个整型指针
auto e=&a; //e是一个指向整数常量的指针
若希望推出的auto类型是一个顶层const,需明确指出
const auto f=a; //a的推演类型是int ,f是const int
将引用类型设为auto
auto &g=a; //g是一个整型常量引用,绑定到a
auto &h=1; //错误,不能为非常量引用绑定字面值
const auto &j=1; //正确,可以为常量引用绑定字面值
decltype类型指示符
decltype处理const语句
const int a=0,&b=a;
decltype(a) x=0; //x的类型是const int
decltype(b) y=X; //y的类型是const int &,y绑定到变量x
decltype(b) z; //错误,引用必须初始化
decltype的表达式如果是加上了括号的变量,结果将是引用
双层括号的结果永远是引用,单层括号里本身是一个引用时才是引用
int i=1;
decltype((i)) d; //错误,d是int &(引用)必须初始化
decltype(i) e; //正确,e是一个未初始化的int型数据
预处理器 (可有效防止重复包含的发生)
(1) #define :把一个名字设定为预处理变量
(2) #ifdef: 当且仅当变量已定义时为真
(3) #ifndef:当且仅当变量未定义是为真
一旦结果检查为真,则执行操作直到遇到#endif为止