指针(P47)
- c++11后,初始化空指针用 nullptr。以前的NULL是预处理变量
- 指针的指针,数据结构已经说得够多了,两次解引用是原值,一次解引用是指针
- 指针的引用:(引用本身不是一个,所以没有引用的指针)
int *&r = p
//右到左,里到外,&表示是一个引用,*表示是一个指针类型的引用
Const (P53)
const int i = get_size(); //运行时初始化
const int j = 42; //编译初始化
const int k; 错误,k未被初始化常量
- const只对自己文件内的变量管用,如果其他文件定义了同名变量,则不会被const
- 如果用了extern,其他文件只需要定义一下,就能使用和初始文件一样的常量
#include<bits/stdc++.h>
#include"constTest.h"
using namespace std;
int main()
{
extern const int a; //这里
cout << a;
return 0;
}
//单独定义的头文件
#include<iostream>
using namespace std;
extern const int a = 10;
常量引用(P55)
- 通常引用类型必须和对象一致,有例外:表达式初值可以被转化成引用的类型
/*-----保持一直-----*/
const int ci = 1024;
const int &r1 = ci; //正确,都是常量。r1不能改变值
int &r2 = ci; //错误,不能 非 常量引用指向常量
/*------例外------*/
int i = 42;
const int &r1 = i; //允许
const int &r2 = 42; //允许,r1是常量引用
int &r4 = r1 * 2; //错误!
//编译器会生成中间值,同理于下面
double dval = 3.14;
const int &ri = dval;//错误!中间值const int temp = dval;整数化
- const引用不可以改值
指针和const
- 统一,不可以改 | 底层const(靠左)
const double pi = 3.14
double *ptr = π // 不行,ptr是普通指针
const double *cptr = &pi; //可以
*cptr = 1; //不能改值
- 常量指针,指针指向不能改变 | 顶层const(靠右)
int eNum = 1;
int *const cNum = &eNum;
Constexpr (P58)(const expression)
- 类似const,而且,在编译阶段就可以获得值。
- (可以交给编译器判断是否是常量表达式)
constexpr 与 指针
- constexpr仅对指针有效,与指针所指对象无关(又是一个细节)
const int *p = nullptr; //p指向一个整型常量,底层const
constexpr int *q = nullptr; //q是常量,指向一个整数,转化成顶层指针
- constexpr 可以指向一个常量也可以指向一个非常量
类型别名 typedef, using(P61)
注意
把typedf别名理解成名字替换本质上是错的,有时候会出现意想不到的错误
typedef char *pstring;
const pstring cstr = 0; //指向char的常指针,不是之前的任意两种理解的const,不能理解成 const char * cstr = 0;
//typedef本质是定义了一个指针,pstring是一个指针,而改写后的const char类型。
对照验证实验,一个可以改值,一个不可以改值

auto, decltype
- 只会推断一次, 引用当原来的类型,不能为非常量引用绑定字面值
int i, *p;
auto ci = i, cp = p; //错误,auto先被推断成int了
//引用当原来的类型
int c = 1, & cr = c;
auto b = cr; //b是int形状
//不能为非常量引用绑定字面值
auto &h = 42; //错误!
const auto &j = 42; //正确,因为没有改变值的风险
- decltype可以根据表达式推断类型, 如果加上了括号永远是引用
int i = 42, *p = &i, &r = i;
decltype(r+0) b; //可以,int型
decltype(*p) c; //错误,解引用表达式,c为引用类型,需要初始化
decltype( (i) ) d = i; //d是引用
头文件保护
如果

运算符
- 一、二、三元运算符
左值 右值
- 通常能返回地址的是左值,否则右值
在表达式
- 多数情况下不会明确求值顺序
int i = f1() + f2(); //不确定f1和f2调用的先后顺序
int i = 0; cout << i << ’ ’ << ++i << endl;
//一般在表达式改变了某个值,就不要在表达式其他地方再使用这个运算对象(一般使用编译器的时候看不出来影响)
- 位运算最好用无符号位。
- 位运算应用

unsigned long quizl = 0; //
quizl |= 1UL << 27; //27通过测试。取或。
quizl &= ~(1UL << 27); //27没通过,与。同为否都为否
boolstatus= quizl & (1UL << 27);//27是否通过。
显示强制转换
char c = '9';
int a = static_cast<int>(c);
//新版本常用static_cast,旧风格用(type)expr
//如果有底层const,用const_cast


被折叠的 条评论
为什么被折叠?



