C++Primer第5版读书笔记(第4章)

第4章 表达式
4.1.1 基本概念

  1. 小整数类型(如bool、char、short等)通常会被提升成较大的整数类型;

    • 赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
    • 取地址符作用与一个左值运算对象,返回一个指向运算对象的指针,这个指针是一个右值。
    • 内置引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。
    • 内置类型和迭代器的递增递减运算符作用与左值运算对象,其前置版本所得的结果也是左值。
  2. 如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。例如:假设p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&,另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整数指针的指针。

4.1.3 求值顺序

  1. 优先级规定了运算对象的组合方式,但是没有说明运算对象按照什么顺序求值。如下表达式,无法确认f1和f2谁先调用。
int i=f1()*f2();
int j=0;
cout<" "<<++j<//未定义的
 2. 有四种运算符明确规定了运算对象的求值顺序,逻辑与(&&)、逻辑或(||)、条件运算符(?:)和逗号运算符(,);

4.2 算术运算符

  1. 参与取余运算的运算对象必须是整数类型,(-m)/n和m/(-n)都等于-(m/n),m%(-n)等于m%n,(-m)%n等于-(m%n);

4.9 sizeof运算符

  1. sizeof运算符的结果部分地依赖与其作用的类型:
    • 对char或者类型char的表达式执行sizeof运算,结果是1;
    • 对引用类型执行sizeof运算得到被引用对象所占空间的大小;
    • 对指针执行sizeof运算得到指针本身所占空间的大小;
    • 对解引用指针执行sizeof运算得到指针指向的对象所占空间的大小,指针不需有效;
    • 对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理;
    • 对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中元素占用了多少空间;
#include
#include
using namespace std;
struct{
    short a1;
    short a2;
    short a3;
}A;
struct{
    long b1;
    short b2;
}B;
class C1{
    public:
        int a;
        static int b;
        C1();
        ~C1();
};
class C2{
    public:
        int a;
        char c;
        C2();
        ~C2();
};
class C3{
    public:
        float a;
        char c;
        C3();
        ~C3();
};
class C4{
    public:
        float a;
        int b;
        char c;
        C4();
        ~C4();
};
class C5{
    public:
        double d;
        float a;
        int b;
        char c;
        C5();
        ~C5();
};
int main(){
    char *ss1="0123456789";      
    char ss2[]="0123456789";     
    char ss3[100]="0123456789"   
    int ss4[100];               
    char q1[]="abc";            
    char q2[]="a\n";            
    char *q3="a\n";             
    char *str1=(char*)malloc(100);
    void *str2=(void*)malloc(100);
    cout<<sizeof(ss1)<<" ";   //输出值为:4
    cout<<sizeof(ss2)<<" ";   //输出值为:11
    cout<<sizeof(ss3)<<" ";   //输出值为:100
    cout<<sizeof(ss4)<<" ";   //输出值为:400
    cout<<sizeof(q1)<<" ";    //输出值为:4
    cout<<sizeof(q2)<<" ";    //输出值为:3
    cout<<sizeof(q3)<<" ";    //输出值为:4
    cout<<sizeof(A)<<" ";     //输出值为:6
    cout<<sizeof(B)<<" ";     //输出值为:8
    cout<<sizeof(str1)<<" ";  //输出值为:4
    cout<<sizeof(str2)<<" ";  //输出值为:4
    cout<<sizeof(C1)<<" ";    //输出值为:4
    cout<<sizeof(C2)<<" ";    //输出值为:8
    cout<<sizeof(C3)<<" ";    //输出值为:8
    cout<<sizeof(C4)<<" ";    //输出值为:12
    cout<<sizeof(C5)<<" ";    //输出值为:24
}

4.11.3 显示转换

  1. 一个命名的强制类型转换具有如下形式:
cast-name<type>(expr);

cast-name是static_cast、dynamic_cast、const_cast和reinterpret_cast中的一种。

 2. static_cast任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。
 3. const_cast只能改变运算对象的底层const;
 4. reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。

4.12 运算符优先级
C++Primer第5版读书笔记(第4章)_第1张图片
C++Primer第5版读书笔记(第4章)_第2张图片
C++Primer第5版读书笔记(第4章)_第3张图片

你可能感兴趣的:(C++)