---恢复内容开始---

## 内存管理
### new/delete
C语言中提供了 malloc 和 free 两个系统函数,#include "stdlib.h"库函数,完成对堆内存的申请和释放。而 c++则提供了两关键字 new 和 delete ,new delete关键字。
**生成单变量空间和数组空间**

int *p = (int *)malloc(sizeof(int));//c

int *p = static_cast<int*>(malloc(sizeof(int)));//c过渡到c++
int *p = new int(200);//C++单变量初始化
cout<< *p<<endl;
string *ps = new string("assassin");
cout<< *ps<<endl; struct Stu
{
int age;
string name;
};
Stu* pStu = new Stu{23,"assassin"};
cout<< pStu->age<<endl;
cout<< pStu->name<<endl;
//23
//assassin

生成数组

char *p = new int[4];
strcpy(p,"china");
cout<<p<<endl; int *pi = new int[5];
//int *pi = new int[5]{0};//初始化0,一般不这样
memset(pi,0,sizeof(int[5]));//初始化
for(int i = 0;i < 5;i++)
{
cout<<pi[i]<<endl;
}

生成指针数组:

char **p = new char*[5]{NULL};
p[0] = "assassin";
p[1] = "automan";
p[2] = "wunworld";
while(*p)
{
cout<<*p++<<endl;
}
/*
assassin
automan
wunworld
*/

生成二维数组;

int (*pa)[4] = new int[3][4]{{0}};//初始化
for(int i = 0;i < sizeof(int[3][4])/sizeof(int[4]);i++)
{
for(int j = 0;j < 4;j++)
{
cout<<pa[i][j]<<" ";
}
cout<<endl;
}
/*
0 0 0 0
0 0 0 0
0 0 0 0
*/
//多维
int (*ppp) [3][4][5] = new int[2][3][4];

释放delete:

int *p = new int;
delete p;
int *a = new int[100];
delete []a;//正确的释放
delete a;//只把第一个释放了 int (*aa)[4] = new int[3][4];
delete []aa;//多位的数组也是一个方括号,底层用递归

注意事项

1,new/delete 是关键字,效率高于 malloc 和 free.

2,配对使用,避免内存泄漏和多重释放。

3,避免,交叉使用。比如 malloc 申请的空间去 delete,new 出的空间被 free;

//c
int *p = (int *)malloc(100);
if(NULL == p)
return -1;
//c++
int *pi = new (std::nothrow) int[100];
if(pi == NULL)
return -1;

内联函数(inline function)

c语言中有宏函数的概念。宏函数的特点是内嵌到调用代码中去,避免了函数调用的开销。但是由于宏函数的处理发生在预处理阶段,缺失了语法检测和有可能带来的语意差错,容易使得内存text段体积变大,不会类型检查。

#define SQR(i) ((i)*(i))
int main()
{
int i=0;
while(i<5)
{
// printf("%d\n",SQR(i++));
printf("%d\n",sqr(i++));
}
return 0;
} int sqr(int i)
{
return i*i;
}
/*
优点:一段高度抽象的逻辑,不易产生歧义,是的text段体积变小,会类型检查。
缺点:函数调用的压栈与出栈的开销
*/

内联函数兼有宏和函数的优点。系统自己有一套优化方案,inline变成了给编译器的一种建议。

inline int sqr(int i)
{
return i*i;
}

评价

优点:避免调用时的额外开销(入栈与出栈操作)

代价:由于内联函数的函数体在代码段中会出现多个“副本”,因此会增加代码段的空间。

本质:以牺牲代码段空间为代价,提高程序的运行时间的效率。

适用场景:函数体很“小”,且被“频繁”调用。

强制类型转化

static_cast
//对于隐时类型可以转化的
reinterpret_cast
//对于无隐式的类型转化,static_cast不可用
const_cast
//
dynamic_cast
//

static_cast

float a = 5.6;
int b = 5; b = static_cast<int>(a);//把a转成int赋值给b void *p,int *q;
p = q;//可以
q = p;//不可以,任何指针都可以赋值给void *类型,但是void *类型不可以赋值给指针类型。
q = static_cast<int*>(p);

reinterpret_cast

int a[5] = {1,2,3,4,5};
int *p = reinterpret_cast<int*>((reinterpret_cast<int>(a)+1));

const_cast

( 脱) 常类型转换,只能引用与指针与引用

const 一定不可以修改

void func(const int &r)
{ }
void func2(int & v)
{
cout<<v<<endl;
} int main()
{
const int a = 19;
func(10);//可以
func(a+10);//可以,应为参数中有const修饰。
func2(const_cast<int&>(a));//因为a是const int类型
int & ra = const_cast<int&>(a);
ra = 200;
cout<<"a = "<<a<<" ra= "<<ra<<endl;
cout<<"&a = "<<&a<<" ra = "<<&ra<<endl;
/*
a = 19 ra = 200
&a = 0x... 不一样
*/
}

用来移除对象的常量性(cast away the constness)使用 const_cast 去除 const 限定的目的不是为了修改它的内容,使用 const_cast 去除 const 限定,通常是为了函数能够接受这个实际参数。

可以改变 const 自定义类的成员变量,但是对于内置数据类型,却表现未定义行为 .

const 常变量

#defined N 200 //宏,在预处理的阶段发生了替换
const int a = 100;//编译阶段发生了替换
//const 永远不会发生改变

命名空间(namespace scope)

//全局就是无名空间
int v = 55;
int main()
{
int *p = &v;//访问全局的
int v =5;
cout<<v<<endl;//5
cout<<*p<<endl;//55 cout<<::v<<endl;//::作用域运算符,前面要命名空间,平常调配用的函数之前省略:: return 0;
}

namespace 是对全局命名空间的再次划分

#include<iostream>
using namespace std;
namespace Spac{
int a;//全局变量
struct Stu{};//数据类型
void func();//函数
namespace//其它命名空间
}

使用:

#include<iostream>
using namespace std;
namespace Space {
int x;
int y;
}
namespace Other {
int x;
int y;
}
int main()
{
Space::x = 200;//这种与本地的不会冲突
cout<<Space::x<<endl;//200 using Space::x;//在这作用域内的x都是Space命名空间中的x
x = 20;
cout<<x<<endl; using Space Space;//直接把Space这个命名空间打开
x = 20;
y = 30; return 0;
}

各种之间冲突解决

利用最小单位的作用域块

#include<iostream>
using namespace std;//标中库空间命名
namespace Space {
int x;
int y;
}
namespace Other {
int x;
int y;
}
int main()
{
{
using Space Space;
x = 20;
y = 30;
}
{
using Space Other;
x = 50;
y = 70;
}
int x,y; return 0;
}

支持嵌套

namespace Space {
int x;
int y;
namespace Other {
int m;
int n;
}
}
int main()
{
using namespace Space::Other;//使用Other命名空间中的变量,不建议嵌套
m = 30;
return 0;
}

协同开发中的使用

namespace Space {
int x;
}
namespace Space {
int y;
}//命名空间相同会自动合并
int main()
{
using namespace Space;
x = 10;
y = 20;
return 0;
}

系统string类

string是一个类而非关键字,初始化比较灵活(类似js中var)

string s = "assassin";//赋值
string s2 = "assassin1";
cout<<s2.size()<<endl;//大小
string s3 = "wunworld";
s3 += s2;//拼接
if(s == s2)//比较
cout<<"s = s2"<<endl;
else if(s > s2)
cout<<"s > s2"<<endl;
else
cout<<"s < s2"<<endl; char buf[1024];
strcpy(buf,s.c_str());
//如果和字符连用时,一定用c_str(),返回的是char *类型
//交换swap(string &s2)成员函数
s.swap(s2);

查找:

int find(char c, int pos = 0);
int find(char * s, int pos = 0);
//返回下标值,没有找到返回-1,默认从 0 下标开找

eg:

string s = "assassin";
int n = s.find("i",0);
cout<<n<<endl;//6

string 类型数组

string sArray[10] = {
"0",
"1",
"22",
"333",
"4444",
"55555",
"666666",
"7777777",
"88888888",
"999999999",
};
for(int i=0; i<10; i++)
{
cout<<sArray[i]<<endl;
}

string 数组是高效的,如果用二维数组来存入字符串数组的话,则容易浪费空间,此时列数是由最长的字符串决定。如果用二级指针申请堆空间,依据大小申请相应的空间,虽然解决了内存浪费的问题,但是操作麻烦。用 string 数组存储,字符串数组的话,效率即高又灵活。

学习C++的建议:

1、在 C++中几乎不需要用宏,用 const 或 enum 定义显式的常量,用 inline 避免函数 调用的额外开销,用模板去刻画一族函数或类型,用 namespace 去避免命名冲突。

2、不要在你需要变量之前去声明,以保证你能立即对它进行初始化。

3、不要用 malloc,new 运算会做的更好。

4、避免使用 void*、指针算术、联合和强制,大多数情况下,强制都是设计错误的指示器。

5、尽量少用数组和 C 风格的字符串,标准库中的 string 和 vector 可以简化程序。

6、更加重要的是,试着将程序考虑为一组由类和对象表示的相互作用的概念,而不是一堆数据结构和一些可以拨弄的二进制

---恢复内容结束---

## 内存管理

new/delete

C语言中提供了 malloc 和 free 两个系统函数,#include "stdlib.h"库函数,完成对堆内存的申请和释放。而 c++则提供了两关键字 new 和 delete ,new delete关键字。

生成单变量空间和数组空间

int *p = (int *)malloc(sizeof(int));//c

int *p = static_cast<int*>(malloc(sizeof(int)));//c过渡到c++
int *p = new int(200);//C++单变量初始化
cout<< *p<<endl;
string *ps = new string("assassin");
cout<< *ps<<endl; struct Stu
{
int age;
string name;
};
Stu* pStu = new Stu{23,"assassin"};
cout<<pStu->age<<endl;
cout<<pStu->name<<endl;
//23
//assassin

生成数组

char *p = new int[4];
strcpy(p,"china");
cout<<p<<endl; int *pi = new int[5];
//int *pi = new int[5]{0};//初始化0,一般不这样
memset(pi,0,sizeof(int[5]));//初始化
for(int i = 0;i < 5;i++)
{
cout<<pi[i]<<endl;
}

生成指针数组:

char **p = new char*[5]{NULL};
p[0] = "assassin";
p[1] = "automan";
p[2] = "wunworld";
while(*p)
{
cout<<*p++<<endl;
}
/*
assassin
automan
wunworld
*/

生成二维数组;

int (*pa)[4] = new int[3][4]{{0}};//初始化
for(int i = 0;i < sizeof(int[3][4])/sizeof(int[4]);i++)
{
for(int j = 0;j < 4;j++)
{
cout<<pa[i][j]<<" ";
}
cout<<endl;
}
/*
0 0 0 0
0 0 0 0
0 0 0 0
*/
//多维
int (*ppp) [3][4][5] = new int[2][3][4];

释放delete:

int *p = new int;
delete p;
int *a = new int[100];
delete []a;//正确的释放
delete a;//只把第一个释放了 int (*aa)[4] = new int[3][4];
delete []aa;//多位的数组也是一个方括号,底层用递归

注意事项

1,new/delete 是关键字,效率高于 malloc 和 free.

2,配对使用,避免内存泄漏和多重释放。

3,避免,交叉使用。比如 malloc 申请的空间去 delete,new 出的空间被 free;

//c
int *p = (int *)malloc(100);
if(NULL == p)
return -1;
//c++
int *pi = new (std::nothrow) int[100];
if(pi == NULL)
return -1;

内联函数(inline function)

c语言中有宏函数的概念。宏函数的特点是内嵌到调用代码中去,避免了函数调用的开销。但是由于宏函数的处理发生在预处理阶段,缺失了语法检测和有可能带来的语意差错,容易使得内存text段体积变大,不会类型检查。

#define SQR(i) ((i)*(i))
int main()
{
int i=0;
while(i<5)
{
// printf("%d\n",SQR(i++));
printf("%d\n",sqr(i++));
}
return 0;
} int sqr(int i)
{
return i*i;
}
/*
优点:一段高度抽象的逻辑,不易产生歧义,是的text段体积变小,会类型检查。
缺点:函数调用的压栈与出栈的开销
*/

内联函数兼有宏和函数的优点。系统自己有一套优化方案,inline变成了给编译器的一种建议。

inline int sqr(int i)
{
return i*i;
}

评价

优点:避免调用时的额外开销(入栈与出栈操作)

代价:由于内联函数的函数体在代码段中会出现多个“副本”,因此会增加代码段的空间。

本质:以牺牲代码段空间为代价,提高程序的运行时间的效率。

适用场景:函数体很“小”,且被“频繁”调用。

强制类型转化

static_cast
//对于隐时类型可以转化的
reinterpret_cast
//对于无隐式的类型转化,static_cast不可用
const_cast
//
dynamic_cast
//

static_cast

float a = 5.6;
int b = 5; b = static_cast<int>(a);//把a转成int赋值给b void *p,int *q;
p = q;//可以
q = p;//不可以,任何指针都可以赋值给void *类型,但是void *类型不可以赋值给指针类型。
q = static_cast<int*>(p);

reinterpret_cast

int a[5] = {1,2,3,4,5};
int *p = reinterpret_cast<int*>((reinterpret_cast<int>(a)+1));

const_cast

( 脱) 常类型转换,只能引用与指针与引用

const 一定不可以修改

void func(const int &r)
{ }
void func2(int & v)
{
cout<<v<<endl;
} int main()
{
const int a = 19;
func(10);//可以
func(a+10);//可以,应为参数中有const修饰。
func2(const_cast<int&>(a));//因为a是const int类型
int & ra = const_cast<int&>(a);
ra = 200;
cout<<"a = "<<a<<" ra= "<<ra<<endl;
cout<<"&a = "<<&a<<" ra = "<<&ra<<endl;
/*
a = 19 ra = 200
&a = 0x... 不一样
*/
}

用来移除对象的常量性(cast away the constness)使用 const_cast 去除 const 限定的目的不是为了修改它的内容,使用 const_cast 去除 const 限定,通常是为了函数能够接受这个实际参数。

可以改变 const 自定义类的成员变量,但是对于内置数据类型,却表现未定义行为 .

const 常变量

#defined N 200 //宏,在预处理的阶段发生了替换
const int a = 100;//编译阶段发生了替换
//const 永远不会发生改变

命名空间(namespace scope)

//全局就是无名空间
int v = 55;
int main()
{
int *p = &v;//访问全局的
int v =5;
cout<<v<<endl;//5
cout<<*p<<endl;//55 cout<<::v<<endl;//::作用域运算符,前面要命名空间,平常调配用的函数之前省略:: return 0;
}

namespace 是对全局命名空间的再次划分

#include<iostream>
using namespace std;
namespace Spac{
int a;//全局变量
struct Stu{};//数据类型
void func();//函数
namespace//其它命名空间
}

使用:

#include<iostream>
using namespace std;
namespace Space {
int x;
int y;
}
namespace Other {
int x;
int y;
}
int main()
{
Space::x = 200;//这种与本地的不会冲突
cout<<Space::x<<endl;//200 using Space::x;//在这作用域内的x都是Space命名空间中的x
x = 20;
cout<<x<<endl; using Space Space;//直接把Space这个命名空间打开
x = 20;
y = 30; return 0;
}

各种之间冲突解决

利用最小单位的作用域块

#include<iostream>
using namespace std;//标中库空间命名
namespace Space {
int x;
int y;
}
namespace Other {
int x;
int y;
}
int main()
{
{
using Space Space;
x = 20;
y = 30;
}
{
using Space Other;
x = 50;
y = 70;
}
int x,y; return 0;
}

支持嵌套

namespace Space {
int x;
int y;
namespace Other {
int m;
int n;
}
}
int main()
{
using namespace Space::Other;//使用Other命名空间中的变量,不建议嵌套
m = 30;
return 0;
}

协同开发中的使用

namespace Space {
int x;
}
namespace Space {
int y;
}//命名空间相同会自动合并
int main()
{
using namespace Space;
x = 10;
y = 20;
return 0;
}

系统string类

string是一个类而非关键字,初始化比较灵活(类似js中var)

string s = "assassin";//赋值
string s2 = "assassin1";
cout<<s2.size()<<endl;//大小
string s3 = "wunworld";
s3 += s2;//拼接
if(s == s2)//比较
cout<<"s = s2"<<endl;
else if(s > s2)
cout<<"s > s2"<<endl;
else
cout<<"s < s2"<<endl; char buf[1024];
strcpy(buf,s.c_str());
//如果和字符连用时,一定用c_str(),返回的是char *类型
//交换swap(string &s2)成员函数
s.swap(s2);

查找:

int find(char c, int pos = 0);
int find(char * s, int pos = 0);
//返回下标值,没有找到返回-1,默认从 0 下标开找

eg:

string s = "assassin";
int n = s.find("i",0);
cout<<n<<endl;//6

string 类型数组

string sArray[10] = {
"0",
"1",
"22",
"333",
"4444",
"55555",
"666666",
"7777777",
"88888888",
"999999999",
};
for(int i=0; i<10; i++)
{
cout<<sArray[i]<<endl;
}

string 数组是高效的,如果用二维数组来存入字符串数组的话,则容易浪费空间,此时列数是由最长的字符串决定。如果用二级指针申请堆空间,依据大小申请相应的空间,虽然解决了内存浪费的问题,但是操作麻烦。用 string 数组存储,字符串数组的话,效率即高又灵活。

学习C++的建议:

1、在 C++中几乎不需要用宏,用 const 或 enum 定义显式的常量,用 inline 避免函数 调用的额外开销,用模板去刻画一族函数或类型,用 namespace 去避免命名冲突。

2、不要在你需要变量之前去声明,以保证你能立即对它进行初始化。

3、不要用 malloc,new 运算会做的更好。

4、避免使用 void*、指针算术、联合和强制,大多数情况下,强制都是设计错误的指示器。

5、尽量少用数组和 C 风格的字符串,标准库中的 string 和 vector 可以简化程序。

6、更加重要的是,试着将程序考虑为一组由类和对象表示的相互作用的概念,而不是一堆数据结构和一些可以拨弄的二进制

C/C++(C++内存管理,内联函数,类型转换,命名空间,string类)的更多相关文章

  1. C++内联函数

    在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么在C++中有没有相同的技术或者更好的实现方法呢?答案是有的,那就是内联函数.内联函数作为编译器优化手段的一种技术,在降低 ...

  2. C++解析四-友员函数、内联函数、静态成员

    友元函数 类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员.尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数.友元可以是一个函 ...

  3. C++中内联函数

    目录 什么是内联函数 如何使函数内联 为什么要使用内联函数 inline函数的优缺点分析 什么时候该使用内联函数 正文 在C语言中,我们使用宏定义函数这种借助编译器的优化技术来减少程序的执行时间,那么 ...

  4. 【C++】内联函数(inline)和宏定义(# define)的优劣及其区别

    一.宏定义:# define 1.为什么要使用宏? 因为调用宏比调用函数更有效率,函数的调用必须要将程序的执行顺序转移到函数所存放的内存地址中,将函数程序内容执行完后,再返回到执行该函数前的地方,这种 ...

  5. c++内联函数与静态函数

    不能是虚函数的成员函数有:静态成员函数,内联成员函数,构造函数.没有什么函数需要硬性规定为虚函数,一般析构函数会被定义为虚函数其他就是在继承类中可能需要override的类成员函数应该定义为虚函数 h ...

  6. C++ 类 & 对象-C++ 内联函数-C++ this 指针-C++ 类的静态成员

    C++ 内联函数 C++ 内联函数是通常与类一起使用.如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方. 对内联函数进行任何修改,都需要重新编译函数的所有客户端 ...

  7. c++-内联函数和函数重载和默认参数和函数指针

    内联函数 C++ 内联函数是通常与类一起使用.如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方. 对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编 ...

  8. iOS OC内联函数 inline的详解

    inline 在iOS中的一些框架中,static inline是经常出现的关键字组合. static自不用多说,表示在当前文件中应用,如 static A, 在其它文件中也可以出现static A. ...

  9. volatile,可变参数,memset,内联函数,宽字符窄字符,国际化,条件编译,预处理命令,define中##和#的区别,文件缓冲,位域

    1.volatile: 要求参数修改每次都从内存中的读取.这种情况要比普通运行的变量需要的时间长. 当设置了成按照C99标准运行之后,使用volatile变量之后的程序运行的时间将比register的 ...

随机推荐

  1. CentOS6.5安装redis(3.0.3)

      如果没有安装gcc需要安装gcc 才能编译成功 yum install gcc 离线安装gcc的方法 # rpm -ivh mpfr-2.4.1-6.el6.x86_64.rpm # rpm -i ...

  2. hdu 1518 Square 深搜,,,,花样剪枝啊!!!

    Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. Cannot set web app root system property when WAR file is not expanded

    Cannot set web app root system property when WAR file is not expanded 在tomcat下面可以,在weblogic下面不行的处理方法 ...

  4. POJ - 3321 Apple Tree (线段树 + 建树 + 思维转换)

    id=10486" target="_blank" style="color:blue; text-decoration:none">POJ - ...

  5. 智课雅思词汇---十、pend是什么意思

    智课雅思词汇---十.pend是什么意思 一.总结 一句话总结:[词根含义]:悬挂,垂;称量;支付 词根:-pend-, -pens- [词根含义]:悬挂,垂;称量;支付 [词根来源]:来源于拉丁语动 ...

  6. 递归神经网络——就是解决AST这样的问题

    原文:https://zybuluo.com/hanbingtao/note/626300 有时候把句子看做是词的序列是不够的,比如下面这句话『两个外语学院的学生』: 上图显示了这句话的两个不同的语法 ...

  7. 可以通过shadowserver来查看开放的mdns(用以反射放大攻击)——中国的在 https://mdns.shadowserver.org/workstation/index.html

    Open mDNS Scanning Project 来自:https://mdns.shadowserver.org/ If you are looking at this page, then m ...

  8. VS C/C++ 调用lua库(编译出错)

    导入 lua.h 之类的头文件后,编译含有Lua函数的时候,可能会出现如下错误: 1>main.obj : error LNK2019: 无法解析的外部符号_luaL_checkinteger, ...

  9. exsi的虚拟机加载U盘

    1. 添加usb控制器: 2.添加设备

  10. nginx的gizp压缩

    好处:         页面另存为大小比浏览器传输大小大很多.好处是加快传输.节省带宽.   原理:           浏览器 -> 请求 -> 声明可以接受的压缩方式[http 协议请 ...