笔记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 }
~
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 }
~
- 《创业笔记》笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- 笔记3
- [笔记] 传智播客-javaWeb笔记(3)
- 【笔记篇】C#笔记3
- CCNP_route笔记3 EIGRP基本笔记
- 【笔记】Python 3自学笔记之基础知识
- 【笔记】Python 3自学笔记之函数
- 昆虫繁殖
- python 利用 xlwt 生成excle
- PS制作万圣节南瓜
- TabActivity标签界面的实现
- 在两台linux服务器间传递文件
- 笔记3
- Install Google’s Android Eclipse plugin
- 如何在tomcat部署应用
- J2EE轻量级架构与企业级应用开发
- 无线网络受限时 ipconfig /release ipconfig /renew
- oracle 存储过程 编译、删除时无响应
- 开源库的选择和驾驭
- HDU 2544 最短路
- 批量更改文件编码