C++ primer阅读笔记

day1:

  1. 注释:
//单行注释忽略所有内容
/**/中间不能嵌套
/*碰见*/就会结束
/*sdadasd/**/这一句就不会被注释*/ 

字符型会分为char 、signed char、unsigned cahr三种,其实只会表现为有符号和无符号两种,char是会表现为其他两种中的一种,但是具体表现为哪一种,根据编译器决定。


day2:

赋值给无符号类型超出范围的数,会对整数取模,比如。8bit的unsigned char 可以表示范围为0-255,赋值257的时候会取257%256=1
赋值给有符号类型超出范围的数,结果是未定义的,什么都有可能。

赋值给无符号类型超出范围的数,会对整数取模,比如。8bit的unsigned char 可以表示范围为0-255,赋值257的时候会取257%256=1
赋值给有符号类型超出范围的数,结果是未定义的,什么都有可能。

一个字符串太长可以这样输出:
std::cout<< “a really, really long string literal”
“that spans two lines”<< std::endl;

有符号和无符号计算,结果转换成无符号;无符号结果为负数,会取模

虽然有时候创建变量用=号进行初始化,但初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

声明如果赋值了就变成了定义,
变量只能被定义一次,但是可以声明多次。

extern in i;//声明i
int j;//定义j
extern int a=0;//定义a

day3:

  1. 引用
    引用必须初始化,引用的初始值必须是一个对象,不能是表达式或者字面值(比如返回函数int但是结果是int &a=func(),这就不行,必须确定:例如全区变量,并且函数返回值是int &)。

  2. 指针
    不能直接操作void指针所指的对象,应为不知道是什么类型,但是可以以转换乘任何类型的指针
    创建两个指针时候 int *p1,*p2; int *p1,p2是一个int 指针和一个int

  3. 不管是指针还是变量或者其它标识符,从右往左看,离变量名最近的优先,利于弄清楚定义的真是含义

  4. const
    - const对象也必须初始化
    - 利用一个对象A去初始化另外以一个对象时,A是不是const都无所谓,因为就相当于一个拷贝工作。
    -

double i=0.222;
const int &j=i;
//上面的是可行的,类似于下面的过程
const int tmp = i; //生成临时变量  
const int &j = tmp; //绑定临时变量  

当发生类型转化的时候,都会产生一个临时变量(传值返回也是),临时变量具有常性,不能修改,这就导致j在引用i的时候并不是引用i本身,而是i的临时变量,所以要加上const。

对const的引用可能引用一个并非const的对象

int a=10,b=20;
const int* p1=&a;//可以修改p1,但是不能修改*p1,const修饰的*p1
int * const p2=&a;//const修饰的是p2的指向能力,
//所以可以通过解引用来修改值,但是不能让p2重新指向其他地址。
const int * const p3=&a;
  1. 顶层const和底层const(都是在是指针的情况下)
    顶层const修饰的是*,表示对象本身是常量,指针本身不能变,但它指向的内容可以改变。比如说int * const p,可以改变 * p,但不能改变p本身。
    底层const修饰的是类型,表示指针/引用所指的对象是常量,指针可以改,它变量本身不能改变,比如说const int* p,p是可以改变的,但是p所指向的内容*p不能改变。
  2. 引用+const
	//赋值的时候其实可以从权限角度考虑
	int a = 0;
	// 权限平移
	int& ra = a;
	
	// 指针和引用赋值中,权限可以缩小,但是不能放大
	const int b = 1;
	
	// rb引用b,b只有可读权限,rb可读可写,权限放大,不允许
	//int& rb = b;
	
	// 权限平移
	const int& rb = b;
	
	// rra引用a,权限缩小了,允许
	const int& rra = a;


//函数传参同理
//修改前
//void Count(int& s)
//{

//}
//修改后
void Count(const int& s)
{

}
int main{
	//...上述代码
	Count(a);//可以
	Count(b);//不可以,传参时候b的权限扩大了
	Count(rra);//不可以,同上
}

//函数形参为const的好处
1. 当实参的类型比较大时,复制开销很大(形参初始化时),引用会“避免复制”。(这在传递类对象时比较常用)
2. “避免修改实参”,当使用引用时,如果调用者希望只使用实参并不修改实参,则const可以避免使用该引用修改实参
3. 相比非const引用形参,更具实用性:形参可以使用const对象初始化,可使用字面值或右值表达式的实参来初始化

1.  void  search( const  vector< int > & vec) 避免了实参的复制开销
2. 同a例,可避免对实参做出修改
3. 如下函数,调用时
void  search(string & s); 
search( "hello" );  // Error 实参为字面值常量
void search(const string & s); 
search("hello"); // OK
//再如
void  search( int  & v);
search(v1+v2);    // Error 实参是一个右值,无法给引用赋值(需要左值)
void  search( const  int  & v);
search(v1+v2);    // OK

  1. const+指针
int a = 10;
const int * p1 = &a;//p1不是常量 *p1是常量
int const * p2 = &a;//p2不是常量 *p2是常量
int * const p3 = &a;//p3是常量 *p3不是常量
const int * const p4 = &a;//p4、 *p4是常量
int const  * const p5 = &a;//p5、 *p5是常量

day4:

  1. constexpr类型,即常量类型。给编译器识别的,在编译时候就能验证变量是否为常量
    eg:constexpr int a=0;

  2. 类型别名
    -typedef double wages;//wages是double的别名
    -使用using也行using SI=double//SI是double的别名
    -这里要注意,
    typedef char *pstring;
    const pstring cstr=0; //cstr是指向char的常量指针
    const pstring *ps;//ps是一个指针,指向的对象是指向char的常量指针
    虽然类似于const char *cstr=0,这是是一个指向char常量的普通指针,但是不一样。这里使用别名后,char *和pstring是一个整体,直接就是一个char指针,const就是就是修饰的指针。

  3. auto
    -auto定义的变量必须有初始值,并且auto i=0,j=1;是可以的,因为i和j属于同一类型。auto i=0,j=1.1313;则不行,i和j不属于同一类型。
    -auto一般会忽略掉顶层指针,保留底层,即一般初始化时,结果是指向常量的指针,不会是指针常量,

  4. decltype

decltype(f()) sum;//定义变量sum,sum的类型有f()的返回值类型决定

const in ci=0,&cj=ci;
decltype(ci) x=0;//x的类型是const int
decltype(cj) y=x;//y的类型是const int &,y绑定到x
decltype(cj) z;//错误,引用必须初始化

int i=0;
decltype(i) x;//x的类型是int
decltype((i)) y;//错误,y的类型是 int&必须初始化
decltype((variable))的结果永远是引用 

day5:待更新

  1. 引用
  2. 啥都
  3. 啥都
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值