第4章 表达式
4.1.1 基本概念
- 小整数类型(如bool、char、short等)通常会被提升成较大的整数类型;
- 赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
- 取地址符作用与一个左值运算对象,返回一个指向运算对象的指针,这个指针是一个右值。
- 内置引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。
- 内置类型和迭代器的递增递减运算符作用与左值运算对象,其前置版本所得的结果也是左值。
- 如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。例如:假设p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&,另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整数指针的指针。
4.1.3 求值顺序
- 优先级规定了运算对象的组合方式,但是没有说明运算对象按照什么顺序求值。如下表达式,无法确认f1和f2谁先调用。
int i=f1()*f2();
int j=0;
cout<<j<<" "<<++j<<endl;//未定义的
2. 有四种运算符明确规定了运算对象的求值顺序,逻辑与(&&)、逻辑或(||)、条件运算符(?:)和逗号运算符(,);
4.2 算术运算符
- 参与取余运算的运算对象必须是整数类型,(-m)/n和m/(-n)都等于-(m/n),m%(-n)等于m%n,(-m)%n等于-(m%n);
4.9 sizeof运算符
- sizeof运算符的结果部分地依赖与其作用的类型:
- 对char或者类型char的表达式执行sizeof运算,结果是1;
- 对引用类型执行sizeof运算得到被引用对象所占空间的大小;
- 对指针执行sizeof运算得到指针本身所占空间的大小;
- 对解引用指针执行sizeof运算得到指针指向的对象所占空间的大小,指针不需有效;
- 对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理;
- 对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中元素占用了多少空间;
#include<iostream>
#include<string.h>
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 显示转换
- 一个命名的强制类型转换具有如下形式:
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 运算符优先级