博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++(C++内存管理,内联函数,类型转换,命名空间,string类)
阅读量:4937 次
发布时间:2019-06-11

本文共 10038 字,大约阅读时间需要 33 分钟。

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

内存管理

new/delete

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

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

int *p = (int *)malloc(sizeof(int));//cint *p = static_cast
(malloc(sizeof(int)));//c过渡到c++int *p = new int(200);//C++单变量初始化cout<< *p<
age<
<< pStu->name<

生成数组

char *p = new int[4];strcpy(p,"china");cout<

<

< 5;i++){ cout<
<

生成指针数组:

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

生成二维数组;

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<
<<" "; } cout<

释放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;

//cint *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
(a);//把a转成int赋值给bvoid *p,int *q;p = q;//可以q = p;//不可以,任何指针都可以赋值给void *类型,但是void *类型不可以赋值给指针类型。q = static_cast
(p);

reinterpret_cast

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

const_cast

( 脱) 常类型转换,只能引用与指针与引用
const 一定不可以修改

void func(const int &r){}void func2(int & v){    cout<
<
(a));//因为a是const int类型 int & ra = const_cast
(a); ra = 200; cout<<"a = "<
<<" ra= "<
<

用来移除对象的常量性(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<
<

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

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

使用:

#include
using namespace std;namespace Space { int x; int y;}namespace Other { int x; int y;}int main(){ Space::x = 200;//这种与本地的不会冲突 cout<
<

各种之间冲突解决

利用最小单位的作用域块

#include
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) cout<<"s > 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<
<

string 类型数组

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

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));//cint *p = static_cast
(malloc(sizeof(int)));//c过渡到c++int *p = new int(200);//C++单变量初始化cout<< *p<
age<
<
name<

生成数组

char *p = new int[4];strcpy(p,"china");cout<

<

< 5;i++){ cout<
<

生成指针数组:

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

生成二维数组;

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<
<<" "; } cout<

释放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;

//cint *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
(a);//把a转成int赋值给bvoid *p,int *q;p = q;//可以q = p;//不可以,任何指针都可以赋值给void *类型,但是void *类型不可以赋值给指针类型。q = static_cast
(p);

reinterpret_cast

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

const_cast

( 脱) 常类型转换,只能引用与指针与引用
const 一定不可以修改

void func(const int &r){}void func2(int & v){    cout<
<
(a));//因为a是const int类型 int & ra = const_cast
(a); ra = 200; cout<<"a = "<
<<" ra= "<
<

用来移除对象的常量性(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<
<

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

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

使用:

#include
using namespace std;namespace Space { int x; int y;}namespace Other { int x; int y;}int main(){ Space::x = 200;//这种与本地的不会冲突 cout<
<

各种之间冲突解决

利用最小单位的作用域块

#include
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) cout<<"s > 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<
<

string 类型数组

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

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

学习C++的建议:

1、在 C++中几乎不需要用宏,用 const 或 enum 定义显式的常量,用 inline 避免函数 调用的额外开销,用模板去刻画一族函数或类型,用 namespace 去避免命名冲突。
2、不要在你需要变量之前去声明,以保证你能立即对它进行初始化。
3、不要用 malloc,new 运算会做的更好。
4、避免使用 void*、指针算术、联合和强制,大多数情况下,强制都是设计错误的指示器。
5、尽量少用数组和 C 风格的字符串,标准库中的 string 和 vector 可以简化程序。
6、更加重要的是,试着将程序考虑为一组由类和对象表示的相互作用的概念,而不是一堆数据结构和一些可以拨弄的二进制

转载于:https://www.cnblogs.com/intelwisd/p/8506922.html

你可能感兴趣的文章
《Linux/Unix系统编程手册》读书笔记3
查看>>
10·
查看>>
Iframe高度自适应
查看>>
thinkphp-内置标签
查看>>
qt QTableWidget&&QTableView 导出数据到excel
查看>>
二叉树
查看>>
linux系统日志解析
查看>>
accelerated C++ 中查找url(学习笔记)
查看>>
PhpStorm的破解 汉化
查看>>
Spring---浅谈IOC
查看>>
JAVA开发常用计算机命令
查看>>
check android Media Scanner is running-检查Android Media Scanner 是否在运行
查看>>
tensorflow 笔记
查看>>
Lahey-Fujitsu Fortran v7.1初感受
查看>>
这个世界究竟是怎么了
查看>>
如果博士可以从来
查看>>
关于StreamReader的构造函数
查看>>
jenkins发布maven项目
查看>>
渗透测试技巧分享
查看>>
Java反射机制Reflection
查看>>