C++学习笔记03--表达式

01表达式基础

定义:表达式由一到多个操作数组成,可以求值,通常会返回求值结果.

最基本的表达式:变量\字面值    int x;   x+3;    3+2;

通常表达式包括操作符(运算符) :+  - *  / .....

操作符

特性:

       1.接受几个操作数   一元   ++x ;   x++    二元   1+1;    三元  if x>0? a: b   (唯一的三元操作符)

        2.转化操作数的类型   3+2.5    操作符+将3变为double

        3.操作数是左值还是右值   

        4.结果是左值还是右值

        5.优先级与结合性     优先级:3+2*5    结合性:默认左结合   可以通过括号改变  3+(2+5)

        6.操作符的重载   ---只改变运算符的逻辑  不改变操作数的个数,优先级和结合性

操作数的求值顺序是不确定的   

         

fun(int x,int y)
{ .....}

int main()
{
    int a;
    int b; 
    fun(++a,++b)    ++a,和++b执行顺序由底层硬件确定   使执行速度最快  运算效率最高
}
    

左值/右值

C语言:左值可能放在等号左边   右值只能放在等号右边   int x; x=3;    3=x(error)

C++:左值不一定放在等号左边,右值也可能放在等号左边   const int x=3;  x=6 error      右值也可放在左边初始化

左右值的划分都是针对表达式的,不针对对象或数值

        glvalue :泛左值 generalized   ------确定一个对象,位域,或函数的表达式  

                        int x; int y   x=3;  y=4;    x  y 泛左值   3,4纯右值    作为=的操作数

        prvalue :纯右值  prue  作为某个运算符的操作数   初始化某个对象或者位域     

                        ---int x=9;   初始化

        xvalue:将亡值  expiring   代表资源能够被重新使用的对象或者位域    ----std::move(x)   构造将亡值

Note:  

左值转化为右值  int x=4;  int y=x;   

临时具体化  

decltype:

                prvalue------->type                decltype(3) x;   =>int x

                lvalue---------->type &           int x;      decltype  ( (x) ) y=x;   =>int &y=x;

                xvalue---------->type&&          dacltype(std::move(x))  y=std::move(x);     =>int &&y=std::move(x);

类型转换

一些操作符要求操作数具有特定的类型,或者相同的类型   此时可能产生类型转换

隐式类型转换

         自动发生     3+0.5                 "abcd"+4   error

显示类型转换:       ----------------回应如会引入错误   不建议使用 

        static_cast    ----编译期间完成

        const_cast

        dynamic_cast   ----运行期间转换

        reinterpret_cast     重解释

static_cast<>()

cout<<static_cast<double>(3)+0.9<<endl;
cout<<static_cast<double>("abcdef")+3;  error
int x=3;
int y=4;
cout<<x/static_cast<double>(y)<<endl;   ----0.75
cout<<static_cast<double>(x/y)<<endl;    -----0

int *ptr;
void *v=ptr;
int *prt =v;  error
int *ptr2=static_cast<int*>(v);


const_cast<>()

const int *ptr;
static_cast<int*>(ptr);  error
const_cast<int*>(ptr);



reinterpret_cast<>()  ------主要针对指针

int x=3;
double y=reinterpret_cast<double><x>  error
int *ptr=&x;
double *ptr2=reinterpret_cast<double*>(ptr)

C语言类型的类型转换:

        (double)3   

        (int)x

算术操作符

三个优先级:

                一级:   -  +   (一元)      +x;

                二级:  *  /    %   

                三级:   +  -   (二元) 

                7+*3   

均为左结合    1+3-5

操作数和结果均为算术类型的右值      其中加减法与一元加可以接受指针

                int a[3]={1,2,3};  int *ptr=a;   ptr+1;   ptr-1;   end(a)-begin(a)   

                指针相减合法   指针相加不合法

一元+会产生类型提升  :      short x=9;  auto y=+x;     y---int

整数相除会产生整数   向0取整    4/3=1   3/4=0     4/-3=-1

取余只能接受整数类型的操作数  结果符与第一个操作数相同

        4%3=1  

关系操作符

关系操作符 > <  ==  !=   --------  接受算术类型或者指针类型的操作数    ptr !=3  error类型不同

逻辑操作符!  && ||   -------------接受可转化为bool值的操作数

操作数和结果均为纯右值   (结果类型为bool)

出逻辑非外,其他操作符均为左结合     !......右结合  再非

逻辑与   逻辑或  具有短路特性       a&&b    a||b    只要a满足条件  不再判断b

逻辑与的优先级高于逻辑或  a&&b||c

通常  不能将多个关系运算符串联   a<b<c  error

不要写val==true这样的代码

int a=9;
if (a==true)   true转化为1  if(a==1)才执行条件
{......}


if(a)    a=9 非0  执行条件
{....}

 位操作符  >>右移    <<左移

接受右值  进行位运算   返回右值

出取反~外,  其他运算符都是左结合

计算过程可能设计整形提升

这里没有短路逻辑

移位操作符在一定情况下等价于乘  除 2 的幂  但是速度更快

整数的符号与位操作符相关    右移保持符号   左移不能保证符号

               右移后,插入符号位       左移后补0   符号位可能移除

signed char x=3;   00000011  char一个字节  8位
   
cout<<(x<<1)<<endl;  左移一位  00000110   输出6

cout<<(x>>1)<<endl;  右移一位   00000001   输出1


signed char x=-4;     11111100
   
cout<<(x<<1)<<endl;  左移一位  11111000   输出-8

cout<<(x>>1)<<endl;  右移一位   11111110   输出-2

赋值操作符

左操作数为可以修改左值   右操作数为右值 可以转化为左操作数的类型

            int x   ;     x=true  ;

赋值操作符是右结合的    x=y=3;   

求值结果是左操作数          

可以引入大括号初始化列表

复合运算符  x*=3

int x=2;  int y=3;  x^=y^=x^=y      输出x=3   y=2;

自增与自减运算符

分前缀和后缀   ++     --

操作数为左值 ;   前缀返回左值  后缀返回右值

推荐使用前缀形式

int x=9;
x+=1; ------------>x=x+1;
x-=1;  ----------->x=x-1;

x++:
返回运算前的值  内部有临时处理为  int temp=x; x=x+1; return temp;
----占用内存  效率低

++x:
返回运算后的值    x=x+1;  return x;


int x=3;
int y;
y=x++;
cout<<x<<endl; ----->4
cout<<y<<endl; ------>3  返回运算前的值

y=++x;
cout<<x<<endl;--------->4
cout<<y<<endl;--------->4  返回运算后的值

int x=3;
++++x;  ----------->5    右结合    前缀返回左值
x++++;  error  后缀返回右值

其他操作符

成员访问符  .   ->         ->等价(*)

.  操作数是左值(右值)    返回左值 (右值)

-> 操作数是指针  返回左值   

struct  Str
{
    int x;
};

int main()
{
    Str a;
    a.x;
    
    Str*ptr=&a;
    (*ptr).x;
    ptr->x;


}

条件操作符:      a?b:c  唯一的三元操作符

接受一个可转换为bool 的表达式  与两个类型相同的表达式,  其中满足条件只有一个表达式会被求值

如果表达式均是左值返回左值   否则返回右值

右结合

int x=2;
int y=3;
false? 1:x;  返回右值
true? y:x    返回左值 


int score=100;

int res=(score>60)?1:(score>50)?0:-1;   右结合  先右边

逗号操作符:

确保操作数会从左向右求值   cout<<(2,3,4,5)<<endl;      5

求值结果是右操作数

左结合

sizeof操作符:

操作数是一个类型或者一个表达式   sizeof(int)

域解析操作符   ::

函数调用操作符   ()   fun()

索引操作符    X[ ]   ptr[ ]

..........

持续更新.................

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值