写在卸载之前
其实C++这门计算机语言目前只能说会也就是入门 但是不能说精通
所以最近会学一些东西然后不定期整理上去
允许我夹带一波私货
正式开始
1.oct,hex,dec
ta们伴随cout分别输出八进制,十六进制,十进制
#include<bits/stdc++.h>
using namespace std;
int d=99999;
int main()
{
cout<<oct<<d<<endl;//输出八进制
cout<<hex<<d<<endl;//输出十六进制
cout<<dec<<d<<endl;//输出十进制
cout<<bitset<sizeof(d)*8>(d)<<endl;//凭借bitset输出二进制
}
Output
303237
1869f
99999
00000000000000011000011010011111
2.关键字auto
对于变量的自动识别
#include<iostream>
using namespace std;
int main()
{
auto Flag=1;
cout<<"Flag = "<<Flag;
cout<<" , sizeof(Flag)= "<<sizeof(Flag)<<endl;
auto FLAG=true;
cout<<"FLAG = "<<FLAG;
cout<<" , sizeof(FLAG)= "<<sizeof(FLAG)<<endl;
auto NumBer=1000000000000;
cout<<"NumBer = "<<NumBer;
cout<<" , sizeof(NumBer)= "<<sizeof(NumBer)<<endl;
return 0;
}
Output
Flag = 1 , sizeof(Flag)= 4
FLAG = 1 , sizeof(FLAG)= 1
NumBer = 1000000000000 , sizeof(NumBer)= 8
乍一看没有什么了不起 但是在变量类型十分复杂的时候 会让变成容易很多
比如说 我们定义并访问一个vector
vector<int> G;
for(vector<int>::iterator it=G.begin();it<G.end();++it)
我们觉得直接写vector
vector<int> G;
for(auto it=G.begin();it<G.end();++it);
3.存储指针的内存
不管指针指向什么类型的数据 指针所占用的内存单元都相同 都是4字节
4.关键字const用于指针
1) 指针指向的数据为常量不能修改 但是可以修改包含的地址
也就是不能通过指针去修改其所指向的数据
int d=12;
const int* p=&d;//如何定义
*p=13;//这是错误的 不可以修改指向的数据
int dx=13;
p=&dx;//这是正确的 可以修改包含的地址
2) 指针包含的地址为常量不能修改 但是可以修改指向的数据
int d=12;
int* const p=&d;//如何定义
*p=13;//这是正确的 可以修改指向的数据
int dx=13;
p=&dx;//这是错误的 不可以修改包含的地址
3) 指针包含的地址,指向的数据均为常量不能修改 这是最严格的组合
int d=12;
const int* const p=&d;//如何定义
*p=13;//错误
int dx=13;
p=&dx;//错误
这么写的好处是 使用函数传递指针的时候 可以防止函数修改其所指向的值 使得函数更容易维护
5.try,throw,catch异常处理
[【参考出处】](http://c.biancheng.net/view/422.html)
对于程序来说 如果出现的异常了怎么办
1.指针动态内存申请时超出限制
2.数组越界
3.a/b时b=0
4.文件读取时文件不存在
这个时候出现了 try,throw,catch语句
try语句内部运行的时候 通过if-else判断是否出现了人为的异常情况
如果出现了 就通过throw语句抛出异常(注:这里的throw有break的功效 也就是一旦throw了就不会在执行try中之后的语句)
然后catch通过判断异常的类型 输出异常的情况
同样 并列catch也具有优先性 也就是哪个先get到了异常 哪个就先执行 而后面的catch都不会再get异常并执行
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
cin>>n>>m;
try
{
cout<<"before dividing."<<endl;
if(n==0) throw -1;
else if(m==0) throw -1.0;
else cout<<"n/m="<<n/m<<endl;
cout<<"correctly!"<<endl;
}
catch(int d)
{
cout<<"n==0 "<<d<<endl;
}
catch(double e)
{
cout<<"m==0 "<<e<<endl;
}
catch(...)//这个catch语句可以get所有类型的异常 但是由于上面所说的catch的优先性 所以必须放在最后
{
cout<<"all catch!"<<endl;
}
cout<<"finished!"<<endl;
return 0;
}
Sample
Input
6 3
Output
n/m=2
correctly!
finished!
Input
3 0
Output
m==0 -1
finished!
Input
0 4
Output
n==0 -1
finished!
对于一个函数来说 如果当前的异常没有在其内部被get到的话 那么这个异常就会回馈到调用ta的函数 一般称之为上一层函数 直到回馈到main函数
这里就不细说了
6.空间申请时new的变种--new(nothrow)
我们将new替换为new(nothrow) 如果内存超过限制的话 会将申请空间的指针自动转换为空指针NULL
7.引用
“你们抓周树人,跟我鲁迅有什么关系?”
这句话听上去很好笑 但是实际上在程序设计中确实存在
int a;
int b;
b=a;
我们修改b 确实跟a没有什么关系
但是
int a;
int& b=a;
这样的话 就构成了引用 我们修改b也就是在修改a
引用的作用很大
比如说在函数中
returntype function(Type Name);
Result=function(x);
这里等于是将x复制给了Name 如果x占用内存较大 那么复制开销也很大
但是如果使用引用的话 就避免了这份开销
另外 使用引用的话 每一次定义就相当于别名 所以你抓了周树人也就等于抓走了鲁迅
当然了 由于指针存在const防止函数修改 引用也可以通过添加const防止修改
一般来讲 对于内部参数为指针或者引用的函数 推荐后者 因为指针可能会无效 而且引用更简单