C++ primer读书笔记(四)

前言

不知不觉都已经9月30号了,现在实验室里面也就3个人了,大家都回家去给祖国母亲庆生了。来学校已经一个月了,感受还是很多的,确实效率比起在本科的时候还是要高很多。今年元旦买的一本书看了8个月也才看一半,到学校一周就把剩下的一把半看完了,还看完了《MySQL必知必会》。确实这个效率就感觉高很多。之前买的那一本C++primer是一本盗版书,导致看书的时候很不爽,有很大一股味道。很多人会说盗版书也是一样的看,首先我们应该尊重作者的版权,另外对于自身影响很大的是盗版书使用的油墨以及纸张质量都相当垃圾,感觉看书像在吸汽车尾气的感觉。后来我又在京东买了一本正版的书,确实舒服多了。这一章还是在继续继承C语言的一些遗志。我也只说一些不同的地方,相同的地方就不再赘述了。

左值和右值

首先给出官方定义

  • 当一个对象被用作右值时,用的是对象的值
  • 当一个对象被用作左值时,用的是对象的身份(在内存中的位置)

例如a = b;即将b(右值-数据值)赋值到a(左值-地址值)

在这个里面需要注意的是赋值运算符需要一个(非常量)左值作为其左侧运算符。得到的结果仍然是一个左值。

但是对于decltype来说左值和右值所得到的最终结果是不一样的,这一点是大家需要注意的地方。

decltype(*p);   //int& 引用,*p是一个右值
decltype(&p);	//int ** 指针的指针,&p是一个左值

算术运算符

这里面需要注意的地方就是,布尔值不应该参与运算。这里我们用-b来作为一个反面例子

bool int int bool
b=true b=1 b=-1 b=true

得到最后结果就是,b=ture,但是-b也等于ture。这个和现实明显不同,所以我们不应该把布尔值参与运算中,可能会导致一些不可预估的情况出现。
另外进行比较运算时除非比较对象是布尔类型,否则不要使用布尔字面值true和false。

sizeof

sizeof运算符的运算对象有两种形式:

  1. sizeof (type);
  2. sizeof expr;

这两种形式基本一致,对于sizeof来说和其他的函数不同的地方在于,sizeof并不计算其运算对象的值

例如sizeof(*p);对于sizeof并不关心p是否是一个合法的指针,他只是根据*p的定义返回一个大小值

其中需要注意的几个点就是:

  1. 对引用类型执行sizeof运算得到的被引用对象所占空间的大小
  2. 对指针执行sizeof运算得到的是指针本身所占空间的大小
  3. 对数组执行sizeof运算得到的是整个数组所占空间大小
  4. 对string对象或vector对象执行sizeof得到的是该类型固定部分的大小,而不是内部所包含风的元素个数的大小。

下面将介绍这一部分的核心内容,就是类型转换。

类型转换

隐式转换

int ival = 3.541 + 3;这个时候执行的就是隐式转换,因为为了尽量避免损失精度所以是先把3转化为double,相加后在将结果从double转化为int。下面我们来看一下这个过程。

3.541+3 3.541+3 6.541 6
double int double double double int

常见的转换规则是:

  1. 比int类小的整型提升为较大的整型类型
  2. 在条件中,非布尔值转换成布尔值

另外比较重要的一点就是允许将指向非常量类型的指针转换成指向相应的常量类型的指针。

 int i;
 const int &j = i;
 const int *p = &i;

这个和前面P56的允许指向非常量的指针指向常量对象也是一致的。算术转换用到的概率不高,所以就跳过了。

显式转换

cast-name<type>(expression);
其中type是要转换的目标类型,expression是要转换的值,cast-name是转换的方法。

  • static_cast
    任何具有明确定义的类型转换,只要不包括底层const(有专用转换器),都可以使用这个转换器。
    一种用法就是找回编译器无法自动执行的类型转换。

    void *p = &d;
    double *dp = static_cast<double *>(p);//找回了void*类型
    

    要求就是
    必须使指针类型和转换后的目标类型一致

  • const_cast
    const_cast只能用于改变运算对象的底层const。

    const char *pc;
    char *p = const_cast<char *>(pc);//去掉了const性质
    

    其余的强制类型转化器如果改变const类型编译器将报错

  • reinterpret_cast
    reinterpret_cast为运算对象的位模式提供较低层次的转换。
    但是reinterpret_cast是十分危险的,因为这个转换器很大程度上依赖于机器,编译器对其检验不是很严格,所以有可能会出现很严重错误,但是编译器并没有报错的情况。

  • dynamic_cast
    这个在19.2节对其进行详细介绍,

最后是一个C语言和现有C++的转换方法的对比。以及一个运算符优先级表(查阅)

总结

九月马上就要结束了,还有不到4个小时了。我感觉我这个一个月很充实,比较这么多知识从高密度地区渗透到低密度地区。明天就是十月了,大家一起加油吧!

发布了7 篇原创文章 · 获赞 5 · 访问量 983

猜你喜欢

转载自blog.csdn.net/deng821776892/article/details/101788001
今日推荐