笔记3

来源:互联网 发布:股票付费软件 编辑:程序博客网 时间:2024/04/30 01:00
左值:凡是产生引用的表达式,, 凡是间接操作对象,&,*指针也是 ,凡是有名字对象一定是左值;
const int n=8; 是左值;
即使作一个右赋值操作也是左值
数组是左值,但地址是右值
 语言内建的数组下标 [] 、去引用 * 、赋值 (=, +=, 等 ) 、前置 + + 、—操作符产生左值,    其它操作符产生右值
 返回对象引用的函数产生左值,其它情况产生右值
 左值可以隐式的转换为右值,反之则不可

右值: 产生对象的表达式
 临时对象一定是右值; int(8);  
 局部对象就是右值;

返回函数引用

左值和右值 主要是用作函数
文字常量为右值
文字常量: 值本身是没有对象名字, 值本身就代表这个对象名

++i 和i++的
i++解析
(temp=i;i+=1;temp)   temp是右值,因为他是临时对象
++i;//  过程 i+=1;

能用++i, 就不用i++;
对于整形来说,++i和i++ 性能是一样, 因为他是内置类型,不管怎么执行都是汇编的三条指令;
但是对于迭代器来说
迭代器的前置++和后置++性能是不一样的;
 前置++因为他不会产生临时对象,  性能要高;
而后置++是要产生临时对象;

要对表达式求值
=左边和右边的类型都必须是一样的;   左边是数值,右边是字符串就不行
所以需要对

实参对形参的装换


较大类型的整型向较小类型的整型转换,如 int 型向 char 型转
                                             换,可能出现值溢出的现象
用于告诉编译器被其限定的类型的对象不在编译器控制之下,
                                                     提醒编译器不要对含有该限定符的对象作优化

较小类型向较大类型 转换是自动提升

三种类型装换 方式

C风格的转换 是把旧的类型是按新的方式进行装换

float* fp=(float*) &n;  整形指针不能直接转换成float 类型

上面两种方式都是不推荐用的;
//地址转换成指针来说的话;

较大类型向较小类型转换

unsigned int  n =-1;
值回绕  -1代表正正数的最大值


const  

int const *p

int const n=100;  //他是取的地址指针 int const * 就是指针指向的内容不可改变

// 指针和内容都是const的
const int* const q=&n;
int const* const q=&m;

volatile  

typeid
placement


int* p1=new ;
int* p2=new int(5+7);

void *mp =operator new

int * p3 =new(ip) int;

//-----------------------------------------------------------------------------
void *mp =operator new(sizeof(A)*4); 是一个全局的new操作符, 只是分配空间, 不指定指针;
A *ip =static_cast<A *>(mp);   //
A *P3 = new(ip)A,        //把ip这个指针指向的内存地址赋给p3;
  p3.~A();//   这里是调用这个系够函数   不能直接释放这个指针
A *P4 = new(ip+1)A (8);      
  P4.~A();
operator delete mp;  头文件 <memory>
-------------------------------------------------------------------------------
delete p[] pointer

int* p =new int [5];
delete[] p;  //把数组全部释放
delete p;    //释放数组的第一个元素, 后面不释放;

内存泄漏的:  把这个进程给杀掉 ,这个进程之前所有分配过的占用的内存都会释放掉的


位操作;

低位向高位移;

C++位运算: 前8位向后8位转换;
示0x十六进制数
15=8 + 4 + 2 + 1;
16进制
unsigned short n =0x0102;

0000 0001 0000 0002
向右移8位:
0000 0000 0000 0001

0xff 0000 0000 1111 1111


n=((n>>8)&0xff)   | ((n<<8)&ff00);

unsigned int argflags=0xff;
argFlags |=| <<16;  去位操作;

argFlags & ~(1<<16);  求补

位移操作 向前移 向后移的都是

unsigned int oldFlags=0xff;
unsigned int

//转换两个无符号号整形;
与操作 1&1都是1  其他都是0;
expr; 是表达式;

cout<<(n>15 ? "100":"too small");

f1()+f2()+f3();   谁先求值 和编译器有关;  就是可能前一个函数可能需要后一个函数
int f1()
{
}

foo

int i=2;
ar[i]=++i;
结合性  从右向左;
Lambda; 表达式
[]lambda;//就是个函数,函数对象  是个匿名函数

[](int n,int m)
{
    int k=0;
     k=n+m;
    cout<<k<<endl;
}(100,200);
//------------------------------------------------------------------------------------
Lambda 表达式”(lambda expression)是一个匿名函数,它可以包含表达式和语句
I
//---------------------------------------------------------------------------------------
lambda  主要是和 算法库 配合使用;  是个局部对象  想要的时候就用一个;
不用定义后再拿来用;
这个是不用定义就可以拿来用;
用完就扔
一个函数里面不能定义另外一个函数;
[]叫捕获列表
 [X]   作为函数定义他不知道外面有什么;
auto func = [](int& i)   //func是个函数对象;
{
    
}

不一定就是取代函数,
auto func = [&X](int& i)   //func是个函数对象;
{
    //&X 是
}

全局,static, 命令空间的,  不需要捕获就可以使用,[]

auto func = [=,&X](int& i)   //func是个函数对象;
{
    =是所有表达式所有可见的名字传过来
}


auto func = [&](int& i)   //func是个函数对象;
{
    =是所有表达式所有可见的名字都传过来;
}
不加&就是只读,  加& 就是可写的
1,形式
2,场合
3,
Lambda表达式

return new int(8);

安全,稳定,高效


constexpr  叫常量表达式,新标准
constexpr 主要用于修饰函数返回值,表明该函数的返回值是编译时已知的,意即:此函数内仅包含一条形如“return 常量表达式;”这样的语句
//常量表达式就是给编译器优化用的;
因为他只要是常量的话就可以在编译期就计算他的值,在运行期就不用去计算啦

  编译期是可以优化的;
  运行期是不可能被优化;
int n =100;
const int x =n; 可以接受变量,也可以接受常量; 加个constexpr就只接受常量 ,也就是只加const;

constexpr int Y =X;  //他只能接受常量表达式;

常量表达式就是给编译器优化用的;

编译的时候,

const int x=9;

constexpr in y=x;   在函数的返回值上做修饰的;

restrict;//

&  与两个位都为1时,结果才为1

|或 两个位都为0时,结果才为0

^ 异或两个位相同为0,相异为1

(2) 实现两个值的交换,而不必使用临时变量。
    例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
    a = a^b;   //a=10100111
    b = b^a;   //b=10100001
    a = a^b;   //a=0000011

 void swap(int& a,int& b)
    {
            a = a^b;   //a=10100111
           b = b^a;   //b=10100001
           a = a^b;   //a=0000011
    }

   a=10100001
   b=00000110
 a^b=10100111
     

  1 #include <iostream>
  2
  3 using namespace std;
  4
  5
  7 void swap_t(int& a,int& b)
  8 {
  9     a=a^b;
 10     b=b^a;
 11     a=a^b;
 12 }
 13
 14 int main()
 15 {
 16   int a=10;
 17   int b=8;
 18
 19    cout<<"a"<<a<<"b"<<b<<endl;
 20   swap_t(a,b);
 21    cout<<"a"<<a<<"b"<<b<<endl;
 22
 23    return 0;
 24
 25 }                                                                                                                                                 
~