c++学习笔记10 ——运算符

  1. 表达式:一个或多个运算对象组成。
    最简单的表达式是:字面值和变量。
  2. 运算符:
    2.1 一元运算符(作用于一个对象)
      二元运算符
      三目运算符
    2.2 运算符的优先级、结合律、运算对象的求值顺序,运算对象的转换
    2.3 重载运算符:如IO 的<<、>>、string,vector等的迭代器
    2.4 左、右值:一个左值表达式 的求值结果是一个对象或一个函数。
      当一个对象被用作右值时,用的是对象的值(内容),当对象  被用作左值时,用的是对象的身份(内存中的位置)

注1:使用decltype()的时候,左值和右值不同。表达式的结果是左值,使用decltype后得到引用类型,如解引用运算符。当表达式的结果是右值时,如取地址运算符(作用于左值a,表达式结果&a为右值,一个指向该运算对象的指针)

int *p=&a;//解引用运算符生成左值。
 decltype(*p);//该表达式的结果是 int&;
 decltype(&p);//该表达式的结果是int **,指向整形指针的指针。
 decltype(&a);//该表达式的结果是int *,指向a的指针

注2:
1)赋值运算符 = 需要一个左值(非常量的)作为该运算符的左侧运算对象,得到的结果也是一个左值。
2)取地址符:作用于左值运算对象,返回一个指向该运算对象的指针,该指针是一个右值。
3)内置解引用运算符、下标运算符 等求值结果都是左值,
4)内置类型和迭代器的递增递减运算符作用于左值,前置时结果也是左值。

2.2.1 优先级与结合律:
优先级相同,按从左到右的顺序
括号
优先级表:同一组内的运算符优先级相等,组的位置越靠前优先级越高

c++学习笔记10 ——运算符_第1张图片

2.2.2 运算对象的求值顺序:
大多数情况下,不会明确指明求值顺序。
表达式指向并修改了同一对象,会发生错误,如:

cout<<i<<" "<<++i<<endl;

4种明确规定了运算对象的顺序的运算符:逻辑与(&&)、逻辑或(||)、条件(?:)、逗号运算符(,)。

  1. 算术运算符:

    算术运算符:作用于:任意算术类型及任意能转换成算术类型的类型。
      运算对象和求值结果都是右值,求值之前一个表达式里所有的运算会转换成同一类型。
    算术表达式的异常:溢出,除数为0。

注:1)参与取余运算的运算对象必须是整数。
2)int/int 结果还是int。舍弃小数部分,
3)m%n,结果的符号与m相同。

  1. 逻辑和关系运算符:

    逻辑运算符和关系运算符都返回 布尔类型
    关系运算符作用于:算术类型、指针类型
    逻辑运算符作用于:任意能转换成布尔值的类型

运算对象与求值结果都是右值。

逻辑与和逻辑或:短路求值

关系运算符都满足:左结合律
注意关系运算符不能连用。

  1. 赋值运算符:
    赋值运算符的左侧必须是 : 可修改的左值
int i =0;//初始化,非赋值
const int ci = i;//初始化,非赋值
1024 = i;//错,字面值是右值
i+j = k;//算术表达式是右值
ci = k;//ci是常量

如果赋值运算符的左侧运算对象是 内置类型(整型数、浮点数、字符、布尔、void、枚举),则初始化列表最多包含一个值。

赋值运算 满足右结合律,赋值运算的结果是他的左侧运算对象,且是一个左值,当赋值运算符左右两侧的类型不同,右侧的转换为左侧的类型

int i,j;
i=j=0;//靠右的赋值运算j=0作为靠左的赋值运算符的右侧运算对象。
  //赋值运算返回左侧运算对象,靠右的赋值运算的结果(j=0)赋给i

int i,*p;
i=p=0;//错误,p是指针,不能作为右值赋给int型的i

赋值运算符的优先级较低,与其他运算符混用时,应该注意加括号。

  1. 递增、递减运算符:
int i=0,j;
j=++i;//i=1,j=1
j=i++;//i=2,j=1

前置得到相加之后的值
后置得到相加之前的值

尽量用前置版本,当既需要把某一个值加1,且还要使用加之前的值,使用后置版本。

后置的递增运算符的优先级高于解引用运算符:

递增运算符改变了某个运算对象的值,所有在复合语句中,要小心使用,注意运算顺序。

*beg = toupper(*beg++);//错误,赋值语句左右都用到了beg,右侧又改变了beg,

*beg=toupper(*beg);
++beg;
  1. 成员访问运算符:
    点运算 . 和箭头运算 -> 都可以访问 成员
    (*p).men() 等价于 p->men()

  2. 条件运算符:满足右结合律
    即三目运算符:?:
    条件?表达式1:表达式2

条件成立返回表达式1,不成立返回表达式2

可以嵌套,不宜超过3层
(grade>90)?“youxiu”:(grade>60)?“pass”:failed"

  1. 位运算符:
    作用于整数类型的运算对象 ,并把运算对象看成是 二进制位 的集合,最好只作用于 无符号的整数类型。

注:输入输出的<< >>等是标准IO库对位运算符的重载,这两种运算符的内置含义是对其运算对象进行基于二进制位的移动操作。

令左侧运算对象的内容按照 右侧运算对象的要求移动指定的位数(可能会进行类型提升),将移动后的左侧运算对象作为求值结果。右侧运算对象不能为负,且值必须小于结果(有可能进行提升)的位数。

位求反运算符:逐位求反
位与、位或:逐位求与或者或
位异或:逐位,对应位置有且只有一个为1 ,则该位结果为1 .
移位运算符:优先级与结合律
满足左结合律。比算数运算符优先级低,比关系运算符、赋值运算符、条件运算符优先级高。

  1. sizeof运算符:
    :返回一个 表达式 或 类型名字 所占的字节数。
    满足右结合律,返回的类型:size_ t类型的常量表达式
    注:并不实际计算运算对象的值。

1)对char类型的使用sizeof,结果为1
2)对引用类型使用,结果为被引用对象所占空间的大小
3)对指针使用,指针本身所占的空间大小。本机器为8,无论是指向int还是double,还是数组。
4)对解引用的指针使用,指针所指向的对象所占的空间大小
5) 对数组使用,整个数组所占的空间大小,等价于把整个数组中的元素分别sizeof,在求和,
6)对string、vector 使用,得到该类型固定部分的大小,对本机器string为32,vector为24.

#include 
#include 
#include 
#include 
#include 

using namespace std;


int main()
{ 
	
	string s1("aav");//使用括号,只能有1个“ ”,string s{"hah","hha"}错误
	string s2("hahh hahs");//sizeof后,string对象的固定大小32
    cout<<"s2="<<s2<<endl;//输出的带空格即:s2=hahh hahs

	vector <int> v1{0,1,2,3};//sizeof后,vector固定大小24
	vector <string> v2{"string","hah","hehe"};//固定大小24

        int ch1[]={0,1,2,3};//数组以逗号隔开
        int ch2[3][4]={0,1,2,3,2,3,4,5,3,4,5,6};//多维数组以逗号隔开,每一维可以使用花括号扩起来
	char ch3[]={'a','b','c', 'd'};//字符数组,没有最后的空字符串结束,不是c风格字符串
        char ch4[]={"hah adsoaj !"};//c风格字符串,末尾有空字符结束符。
        string ch5[]={"haha","heheh"};//string类数组,字符串数组
        string ch6[4]={"haha","heheh"};//字符串数组

	cout<<"bool="<<sizeof(bool)<<endl;//1
	cout<<"char="<<sizeof(char)<<endl;//1
	cout<<"wchar_t="<<sizeof(wchar_t)<<endl;//4
	cout<<"char16_t="<<sizeof(char16_t)<<endl;//2
	cout<<"char32_t="<<sizeof(char32_t)<<endl;//4
	cout<<"short="<<sizeof(short)<<endl;//2
	cout<<"int="<<sizeof(int)<<endl;//4
	cout<<"long="<<sizeof(long)<<endl;//8
	cout<<"long long="<<sizeof(long long)<<endl;//8
	cout<<"float="<<sizeof(float)<<endl;//4
	cout<<"double="<<sizeof(double)<<endl;//8/
	cout<<"long double="<<sizeof(long double)<<endl;//16

	cout<<endl<<"string s1="<<sizeof(s1)<<endl;//32
	cout<<"string s2="<<sizeof(s2)<<endl;//32

	cout<<endl<<"vector v1="<<sizeof(v1)<<endl;//24
	cout<<"vector v2="<<sizeof(v2)<<endl;//24
	
	cout<<endl;
	cout<<"shuzu1="<<sizeof(ch1)<<endl;//4(int)*4(个元素)=16
	cout<<"shuzu2="<<sizeof(ch2)<<endl;//4(int)*m*n(维度)=48
        cout<<"shuzu3="<<sizeof(ch3)<<endl;//1(char)*4=4
	cout<<"shuzu4="<<sizeof(ch4)<<endl;//13,字符串内容(包含空格)+末尾结束符
     cout<<"字符串数组"<<sizeof(ch5)<<endl;//32*2=64
     cout<<"字符串数组"<<sizeof(ch6)<<endl;//32*4=128

	

return 0;
}

指针、引用相关的sizeof:

#include 
#include 
#include 
#include 
#include 

using namespace std;


int main()
{ 
	
	string s1("aav");//
	string s2("hahh hahs");
        

	vector <int> v1{0,1,2,3};
	vector <string> v2{"string","hah","hehe"};

        int ch1[]={0,1,2,3};//数组以逗号隔开
        int ch2[3][4]={0,1,2,3,2,3,4,5,3,4,5,6};//多维数组以逗号隔开,每一维可以使用花括号扩起来
	char ch3[]={'a','b','c', 'd'};
        char ch4[]={"hah adsoaj !"};



	int a=8,*p1;
    double y=3.13;

        
	int &r=a;//
	double &r2=y;//
	int (&r3)[4]=ch1;//维度不能少,否则不能编译

        int *p2=ch1;
	int *p3=ch2[2];//
        char *p4 = ch3;
        char *p5 = ch4;
        // 注意,string和vector使用下标和迭代器,不使用指针。c风格字符串
        //可以使用指针,指针的类型不能是string啥的,只能是int double啥的。
	
        
        
	cout<<*p2<<" "<<p2<<endl;
	cout<<*p3<<" "<<p3<<endl;
	cout<<*p4<<" "<<p4<<endl;
	cout<<*p5<<" "<<p5<<endl;
	cout<<r<<endl;
	cout<<r2<<endl;
	cout<<r3<<endl;//绑定数组的引用
	cout<<*(r3)<<endl;//输出该数组第一个元素0
	cout<<endl;

	

	

	cout<<endl<<"string s1="<<sizeof(s1)<<endl;
	cout<<"string s2="<<sizeof(s2)<<endl;

	cout<<endl<<"vector v1="<<sizeof(v1)<<endl;
	cout<<"vector v2="<<sizeof(v2)<<endl;
	
	cout<<endl;
	cout<<"shuzu1="<<sizeof(ch1)<<endl;
	cout<<"shuzu2="<<sizeof(ch2)<<endl;
        cout<<"shuzu3="<<sizeof(ch3)<<endl;
	cout<<"shuzu4="<<sizeof(ch4)<<endl;
     
        cout<<"int *="<<sizeof(p1)<<endl;//8,指针本身的大小为8
	 cout<<"zhixiangshuzu de zhizhen "<<sizeof(p2)<<endl;//8,同上
	 cout<<"zhixiang duowei shuzu de zhizhen="<<sizeof(p3)<<endl;//8,同上
	 cout<<"zhixiang zifu shuzu de zhizhen"<<sizeof(p4)<<endl;//8
	 cout<<"c fengge zifuchuan de zhizhen "<<sizeof(p5)<<endl;//8

	cout<<endl;
        
	cout<<"yinyong "<<sizeof(r)<<endl;//4引用的对象是int
        cout<<"yinyong "<<sizeof(r2)<<endl;//8,引用的对象是double
 	cout<<"yinyong 3"<<sizeof(r3)<<endl;//316???为什么?
	

return 0;
}
  1. 逗号运算符:

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